当前位置: 首页 > news >正文

【VS Code插件开发】自定义侧边栏、视图(六)

🐱 个人主页:不叫猫先生,公众号:前端舵手
🙋‍♂️ 作者简介:前端领域优质作者、阿里云专家博主,共同学习共同进步,一起加油呀!
📢 资料领取:前端进阶资料可以找我免费领取
🔥 摸鱼学习交流:我们的宗旨是在「工作中摸鱼,摸鱼中进步」,期待大佬一起来摸鱼(文末有我wx或者私信)

在这里插入图片描述

目录

  • 一、前言
  • 二、registerWebviewViewProvider
  • 三、自定义视图添加到活动栏
  • 四、案例
    • 1、新建`SidebarProvider.ts`文件
    • 2、extension.ts中引入

一、前言

在 VS Code 开发工具中,可以在侧边栏中创建一个持久化的自定义视图。这个视图可以随着 VS Code 的不同窗口、标签页之间的切换而保持存在。

侧边栏官方文档讲解

二、registerWebviewViewProvider

在插件的激活阶段,使用 vscode.window.registerWebviewViewProvider 方法来注册自定义视图的提供者。这个方法接受三个参数,如下:

  • 唯一的视图 ID
  • 用于自定义视图的 HTML 内容、事件处理等
  • 可选的配置选项

当你注册一个 Webview 视图提供者时,需要提供一个回调函数来处理视图的创建和配置。这个回调函数就是 resolveWebviewView。

vscode.window.registerWebviewViewProvider("yourViewId", {resolveWebviewView: (webviewView, context) => {// 在这里设置自定义视图的 HTML 内容、事件处理等webviewView.webview.html = '<h1>Hello from Webview!</h1>';}
}, {webviewOptions: {retainContextWhenHidden: true}
});

retainContextWhenHidden 是布尔类型,用于控制当 Webview 隐藏(不可见)时是否保留其上下文。当设置为 true 时,在用户切换到其他面板或关闭 Webview 时,Webview 的状态和内容将保持不变。这可以在某些情况下提供更好的用户体验,因为用户在返回到 Webview 时可以继续之前的操作,而不必从头开始。

三、自定义视图添加到活动栏

viewsContainers 用于定义自定义视图容器。
activitybar 位于编辑器侧边的垂直工具栏。活动栏提供了快速访问各种功能、面板和操作的图标按钮,使用户能够轻松地切换和执行不同的任务。其中参数如下:

  • id:标识符
  • title:标题
  • icon:图标

views 配置用于定义自定义视图(Views)以及这些视图的属性和行为。这些视图可以包括内嵌的 Webview,以便在插件中显示自定义的 Web 内容、UI 界面等。其中参数解释如下:

  • id:视图的唯一标识符,用于在扩展中引用这个视图。
  • name:视图的名称,将在用户界面中显示。用户将通过这个名称来识别视图。
  • type:视图的类型。在这里,设置为 “webview”,表示在视图中使用 Webview 来显示自定义的 Web 内容。

通过使用 viewsContainers"views 配置,可以创建自己的自定义视图和容器,将其添加到活动栏中,并与 Webview 结合以显示自定义的界面和内容。

"viewsContainers": {"activitybar": [{"id": "wxRead-container","title": "wxRead","icon": "media/logo.png"}]
},"views": {"wxRead-container": [{"id": "wxRead-view","type": "webview","name": "wxRead"}]}

结果展示如下
在这里插入图片描述

四、案例

我们自定义视图的时,简单的可以直接在registerWebviewViewProvider的第二个参数进行设置,不过我们处理复杂的逻辑的时候,一般会封装一个视图,然后引入到extension.ts中使用。

1、新建SidebarProvider.ts文件

在构造函数中,传入扩展的根路径 _extensionUri 和扩展的上下文 context。通过 _context.globalState.get('Token') 获取之前存储的 token。

resolveWebviewView 方法中,配置 Webview 的选项,使其支持运行脚本和加载本地资源。

使用 webviewView.webview.onDidReceiveMessage 监听 Webview 内的消息,并根据不同的 data.command 执行不同的操作。在这个示例中,包括处理登录和登出请求。

loginRequest 方法用于发送登录请求,通过 axios 发送 POST 请求到服务器,处理服务器返回的数据。

_getHtmlForWebview 方法用于生成 Webview 的 HTML 内容。它通过 asWebviewUri 方法获取资源文件的 URI,设置 Content Security Policy(CSP),并嵌入需要加载的脚本和样式。

其中某些参数的解释:

  • enableScripts: true:
    这个选项设置为 true,允许在 Webview 中运行 JavaScript 脚本。如果你的 Webview 需要执行一些交互式操作或展示动态内容,你需要将这个选项设置为 true。

  • localResourceRoots: [this._extensionUri]:
    localResourceRoots 是一个数组,指定了可以从本地加载的资源的根路径。在这个代码中,this._extensionUri 是扩展的根路径 URI,这表示 Webview 可以从扩展的根路径加载本地资源。

_getHtmlForWebview方法中:

styleResetUri、styleVSCodeUri、scriptUri 和 styleMainUri:这些是通过webview.asWebviewUri方法获取的资源文件的 URI。这些 URI 是扩展中的 CSS 样式表和 JavaScript 脚本的位置。

nonce:这是一个用于 CSP 的 nonce 值,用于限制只有特定 nonce 值的脚本能够被执行。

<meta http-equiv="Content-Security-Policy">:这是 Content Security Policy(CSP)的设置,用于指定允许加载的资源和脚本。它限制了从 https 或扩展目录加载的图像,只允许特定 nonce 值的脚本被执行。

最后,返回的 HTML 包括引用了所需资源的 <link> 标签和 <script> 标签。其中,<script> 标签引用了你的编译后的 JavaScript 脚本,nonce 值用于安全性,以确保只有符合 nonce 条件的脚本被执行。

import * as vscode from "vscode";
import { getNonce } from "./getNonce";
import axios from "axios"
import { error } from "console";
export class SidebarProvider implements vscode.WebviewViewProvider {_view?: vscode.WebviewView;//存储 Webview 视图private _context: vscode.ExtensionContext; // 存储扩展上下文对象private _token: string | undefined;// 存储tokenconstructor(private readonly _extensionUri: vscode.Uri, context: vscode.ExtensionContext) {this._context = context;this._token = this._context.globalState.get('Token');}public resolveWebviewView(webviewView: vscode.WebviewView) {this._view = webviewView;webviewView.webview.options = {enableScripts: true,localResourceRoots: [this._extensionUri],};webviewView.webview.onDidReceiveMessage(async (data) => {console.log(data, data.command, 'command1111111111')switch (data.command) {case "login": {let obj;if (data && data.loginname) {obj = { username: data.loginname, password: data.password }} else {obj = { username: this._userInfo?.loginname, password: this._userInfo?.password }}console.log(this._userInfo, 'this._userInfo')this.loginRequest(obj, webviewView);break;}case "logout": {axios.post( `/logout`,{ username: this._userInfo?.username, password: this._userInfo?.password },{headers: {Authorization: `Bearer ${this._token}`, // 假设 token 的类型是 Bearer token},}).then((res) => {console.log(res, "res")if (res.data.code === 200) {this._isLoggedIn = false;webviewView.webview.html = this._getHtmlForWebview(webviewView.webview)//用于生成 Webview 的 HTML 内容this._context.globalState.update('Token', '');this._token = '';vscode.commands.executeCommand('extension.logoutSuccess');}if (res.data.msg) vscode.window.showInformationMessage(res.data.msg);}).catch(error => {vscode.window.showErrorMessage("服务器连接错误!");})break;}}});}public loginRequest(data: any, webviewView: vscode.WebviewView) {axios.post(`/login`, data).then(res => {if (res.data.code === 200) {webviewView.webview.html = this._getHtmlHome(webviewView.webview);//用于生成 Webview 的 HTML 内容webviewView.webview.postMessage({command: 'loginResponse',success: true,message: { ...res.data, imageUri, password,loginname: data.username }});this._token = res.data.token;vscode.commands.executeCommand('extension.loginSuccess', res.data);vscode.window.showInformationMessage(res.data.msg);} else {vscode.window.showErrorMessage(res.data.msg);}}).catch(error => {vscode.window.showErrorMessage("服务器连接错误!");})}public revive(panel: vscode.WebviewView) {this._view = panel;//将传入的 Webview 视图存储到 _view 成员变量中,用于后续操作}// 在其他地方调用此方法来设置缓存的数据public setData(data: any) {}// 在其他地方调用此方法来获取缓存的数据public getData() {}//用于生成 Webview 的 HTML 内容private _getHtmlForWebview(webview: vscode.Webview) {//asWebviewUri获取资源文件的 URIconst styleResetUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, "media", "reset.css"));const styleVSCodeUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, "media", "vscode.css"));const scriptUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, "out", "compiled/HelloWorld.js"));const styleMainUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, "out", "compiled/HelloWorld.css"));// Use a nonce to only allow a specific script to be run.const nonce = getNonce();let a = 0;a++;return `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><!--Use a content security policy to only allow loading images from https or from our extension directory,and only allow scripts that have a specific nonce.--><meta http-equiv="Content-Security-Policy" content=" img-src https: data:; style-src 'unsafe-inline' ${webview.cspSource}; script-src 'nonce-${nonce}';"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link href="${styleResetUri}" rel="stylesheet"><link href="${styleVSCodeUri}" rel="stylesheet"><link href="${styleMainUri}" rel="stylesheet"></head><body><script nonce="${nonce}" src="${scriptUri}"></script></body> </html>`;}
}

2、extension.ts中引入

import SidebarProvider from './SidebarProvider':这里导入自定义 SidebarProvider 类,用于管理 Webview 视图的创建和交互。

创建 readerViewProvider 实例:通过 new SidebarProvider(context.extensionUri, context) 创建了一个 SidebarProvider 实例,将扩展的根路径和上下文对象传递给它。

使用 vscode.window.registerWebviewViewProvider 注册 Webview 视图提供者:这行代码注册了你的 readerViewProvider 实例作为 'wxRead-view' 标识符的 Webview 视图提供者。同时,通过传递一个配置对象,你设置了 Webview 的选项,其中 retainContextWhenHidden 设置为 true,以便在 Webview 隐藏时保留其上下文。

其中部分参数解释如下:

  • context :用于传递上下文信息和提供功能的对象。

  • context.extensionUri:用于获取当前扩展的根路径的 Uniform Resource Identifier (URI)。这个 URI 表示扩展在文件系统中的位置,可以用于引用扩展中的资源文件、图标、样式表等。具体如下:
    在这里插入图片描述

    import SidebarProvider from './SidebarProvider';const readerViewProvider =new SidebarProvider(context.extensionUri, context)vscode.window.registerWebviewViewProvider('wxRead-view', readerViewProvider, {webviewOptions: {retainContextWhenHidden: true,},});

相关文章:

【VS Code插件开发】自定义侧边栏、视图(六)

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域优质作者、阿里云专家博主&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4e2; 资料领取&#xff1a;前端…...

lv3 嵌入式开发-8 linux shell脚本函数

目录 1 函数的定义 2 函数的调用 3 变量的作用域 4 练习 1 函数的定义 基本语法&#xff1a; function name() {statements[return value] }function是 Shell 中的关键字&#xff0c;专门用来定义函数&#xff1b; name是函数名&#xff1b; statements是函数要执行…...

国际版阿里云腾讯云免费开户:服务器怎样转移

阿里云服务器怎样转移 阿里云服务器作为云核算范畴的领军企业之一&#xff0c;为用户供应了高性能、可靠、安全的云服务器服务。随着业务的发展和需求的改动&#xff0c;或许会有需求将阿里云服务器进行转移的情况。本文将介绍阿里云服务器转移的步骤和注意事项&#xff0c;帮…...

区块链实验室(20) - FISCO控制台连接到指定的节点

在FISCO技术文档中&#xff0c;控制台默认采用config.toml作为配置文件&#xff0c;并指定了连接的节点地址和商品&#xff0c;如下所示。 [network] peers["127.0.0.1:20200", "127.0.0.1:20201"] # The peer list to connect在该案例中&#xff0c;控…...

网络渗透day10-工具和技术

以下为网络渗透的工具和技术。 让我更详细地描述网络渗透测试的各个阶段以及使用的工具。 1. 信息收集阶段&#xff1a; 目标识别&#xff1a; 在这一阶段&#xff0c;渗透测试人员确定测试的目标&#xff0c;例如特定的服务器、应用程序或网络。 开放源情报&#xff08;OSIN…...

SSE 和 WebSocket 应用

SSE 和 WebSocket 应用 一.SSE 和 WebSocket 对比二.SSE 和 WebSocket 调试SpringBoot 下 SSE 应用1.依赖2.启动类3.接口类4.Html 测试5.测试结果 SpringBoot 下 WebSocket 应用1.依赖2.启动类3.WS 切点配置4.WS连接类配置5.WS Html 测试6.测试结果 一.SSE 和 WebSocket 对比 …...

mac帧 arp

1.分片 2.MSS max segment size 3.跨网络的本质 就是经历很多的子网或者局域网 4.将数据从A主机跨网络送到B主机的能力 IP和mac IP解决的是路径选择的问题 5.数据链路层 用于两个设备&#xff08;同一种数据链路节点&#xff09;之间进行传递 6.以太网ether 7.局域网通…...

java面试题-Redis相关面试题

Redis相关面试题 面试官&#xff1a;什么是缓存穿透 ? 怎么解决 ? 候选人&#xff1a; 嗯~~&#xff0c;我想一下 缓存穿透是指查询一个一定不存在的数据&#xff0c;如果从存储层查不到数据则不写入缓存&#xff0c;这将导致这个不存在的数据每次请求都要到 DB 去查询&…...

你用过 Maven Shade 插件吗?

文章首发地址 Maven Shade插件是Maven构建工具的一个插件&#xff0c;用于构建可执行的、可独立运行的JAR包。它解决了依赖冲突的问题&#xff0c;将项目及其所有依赖&#xff08;包括传递依赖&#xff09;合并到一个JAR文件中。 下面是对Maven Shade插件的一些详解&#xff…...

Android 后台启动Activity适配

在Android 9及以下版本&#xff0c;后台启动Activity相对自由&#xff0c;但是如果在Activity上下文之外启动Activity会有限制。 Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag所以此时需要给intent添加flag&#x…...

使用element-ui中的el-table回显已选中数据时toggleRowSelection报错

最近在写一个后台&#xff0c;需要在表格中多选&#xff0c;然后点击编辑按钮的时候&#xff0c;需要回显已经选中的表单项 <el-table v-loading"loading" :data"discountList" :row-key"(row) > row.id" refmultipleTable selection-cha…...

Ubuntu18.04系统下通过ROS控制Kinova真实机械臂-多种实现方式

所用测试工作空间test_ws&#xff1a;包含官网最原始的功能包 一、使用Kinova官方Development center控制真实机械臂 0.在ubuntu系统安装Kinova机械臂的Development center&#xff0c;这一步自行安装&#xff0c;很简单。 1.使用USB连接机械臂和电脑 2.Development center…...

聊聊如何玩转spring-boot-admin

前言 1、何为spring-boot-admin&#xff1f; Spring Boot Admin 是一个监控工具&#xff0c;旨在以良好且易于访问的方式可视化 Spring Boot Actuators 提供的信息 快速开始 如何搭建spring-boot-admin-server 1、在服务端项目的POM引入相应的GAV <dependency><grou…...

rocky(centos) 安装redis,并设置开机自启动

一、下载并安装 1、官网下载Redis 并安装 Download | RedisRedisYou can download the last Redis source files here. For additional options, see the Redis downloads section below.Stable (7.2)Redis 7.2 …https://redis.io/download/ 2、上传下载好的redis压缩包到 /…...

Flask狼书笔记 | 06_电子邮件

文章目录 6 电子邮件6.1 使用Flask-Mail发送6.2 使用事务邮件服务SendGrid6.3 电子邮件进阶6.4 小结 6 电子邮件 Web中&#xff0c;我们常在用户注册账户时发送确认邮件&#xff0c;或是推送信息。邮件必要的字段包含发信方(sender)&#xff0c;收信方(to)&#xff0c;邮件主题…...

ChatGPT追祖寻宗:GPT-1论文要点解读

论文地址&#xff1a;《Improving Language Understanding by Generative Pre-Training》 最近一直忙着打比赛&#xff0c;好久没更文了。这两天突然想再回顾一下GPT-1和GPT-2的论文&#xff0c; 于是花时间又整理了一下&#xff0c;也作为一个记录~话不多说&#xff0c;让我们…...

回归拟合 | 灰狼算法优化核极限学习机(GWO-KELM)MATLAB实现

这周有粉丝私信想让我出一期GWO-KELM的文章&#xff0c;因此乘着今天休息就更新了(希望不算晚) 作者在前面的文章中介绍了ELM和KELM的原理及其实现&#xff0c;ELM具有训练速度快、复杂度低、克服了传统梯度算法的局部极小、过拟合和学习率的选择不合适等优点&#xff0c;而KEL…...

Mysql JSON

select json_extract(c2, $.a) select c2->"$.a" // json_extract的语法糖 &#xff08;取出的值会保留"双引号" so不适合实战&#xff09; 注&#xff1a;mysql若是引擎Mariadb则不支持json操作符-&#xff1e;&#xff1e;语法糖 select c2->…...

使用Vue + axios实现图片上传,轻松又简单

目录 一、Vue框架介绍 二、Axios 介绍 三、实现图片上传 四、Java接收前端图片 一、Vue框架介绍 Vue是一款流行的用于构建用户界面的开源JavaScript框架。它被设计用于简化Web应用程序的开发&#xff0c;特别是单页面应用程序。 Vue具有轻量级、灵活和易学的特点&#xf…...

C# 中什么是重写(子类改写父类方法)

方法重写是指在继承关系中&#xff0c;子类重新实现父类或基类的某个方法。这种方法允许子类根据需要修改或扩展父类或基类的方法功能。在面向对象编程中&#xff0c;方法重写是一种多态的表现形式&#xff0c;它使得子类可以根据不同的需求和场景提供不同的方法实现。 方法重…...

【Leetcode-面试经典150题-day22】

目录 97. 交错字符串 97. 交错字符串 题意&#xff1a; 给定三个字符串 s1、s2、s3&#xff0c;请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 两个字符串 s 和 t 交错 的定义与过程如下&#xff0c;其中每个字符串都会被分割成若干 非空 子字符串&#xff1a; s s1 s2 …...

LDAP服务器如何重启

1、find / -name ldap 该命令只会从根路径下查看ldap文件夹 find / -name ldap2、该命令会从根路径/查看所有包含ldap路径的文件夹&#xff0c;会查询出所有&#xff0c;相当于全局查询 find / -name *ldap*2、启动OpenLADP 找到LDAP安装目录后&#xff0c;执行以下命令 #直…...

AP51656 LED车灯电源驱动IC 兼容替代PT4115 PT4205 PWM和线性调光

产品描述 AP51656是一款连续电感电流导通模式的降压恒流源 用于驱动一颗或多颗串联LED 输入电压范围从 5V 到 60V&#xff0c;输出电流 可达 1.5A 。根据不同的输入电压和 外部器件&#xff0c; 可以驱动高达数十瓦的 LED。 内置功率开关&#xff0c;采用高端电流采样设置 …...

浅析安防视频监控平台EasyCVR视频融合平台接入大量设备后是如何维持负载均衡的

安防视频监控平台EasyCVR视频融合平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。视频汇聚融合管理平台EasyCVR既具备…...

SIEM 中不同类型日志监控及分析

安全信息和事件管理&#xff08;SIEM&#xff09;解决方案通过监控来自网络的不同类型的数据来确保组织网络的健康安全状况&#xff0c;日志数据记录设备上发生的每个活动以及整个网络中的应用程序&#xff0c;若要评估网络的安全状况&#xff0c;SIEM 解决方案必须收集和分析不…...

【java基础复习】java中的数组在内存中是如何存储的?

基本数据类型与内存存储数组类型与内存存储为什么数组需要两块空间&#xff1f;感谢 &#x1f496; 基本数据类型与内存存储 首先&#xff0c;让我们回顾一下基本数据类型的内存存储方式。对于一个基本类型变量&#xff0c;例如int类型的变量a&#xff0c;内存中只有一块内存空…...

MySQL数据库 MHA高可用

MySQL MHA 什么是 MHA MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出现就是解决MySQL 单点的问题。 MySQL故障切换过程中&#xff0c;MHA能做到0-30秒内自动完成故障切换操作。 MHA能在故障切换的…...

leetcode669. 修剪二叉搜索树(java)

修剪二叉搜索树 题目描述递归代码演示&#xff1a; 题目描述 难度 - 中等 LC - 669. 修剪二叉搜索树 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留…...

计算机网络的故事——确认访问用户身份的认证

确认访问用户身份的认证 HTTP使用的认证方式&#xff1a;BASIC认证&#xff08;基本认证&#xff09;、DIGEST&#xff08;摘要认证&#xff09;、SSL客户端认证、FormBase认证&#xff08;基于表单认证&#xff09;。 基于表单的认证&#xff1a;涉及到session管理以及cookie…...

C#禁用或启用任务管理器

参考文档https://zhuanlan.zhihu.com/p/95156063 借助上述参考文档里的C#操作注册表类&#xff0c;禁用或启用任务管理器 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace HideTaskMgr { class Program { …...