实现效果:在侧边栏的explorer上加一个视图,视图内展示一个webview
下面将会介绍到
- 向explorer添加一个webview视图.
- webview与wxtension的相互通信
- webview的数据持久化.
- 添加一条命令到view title.
package.json里的配置
vscode注册的命令,视图。必须在package.json中再注册一遍
"contributes": {
"views": {
"explorer": [
{
"type": "webview",//指定类型
"id": "calicoColors.colorsView",//后面要靠这个id进行webview注册
"name": "Calico Colors"
}
]
},
"commands": [
{
"command": "calicoColors.addColor",
"category": "Calico Colors",
"title": "Add Color"
},
{
"command": "calicoColors.clearColors",
"category": "Calico Colors",
"title": "Clear Colors",
"icon": "$(clear-all)"//vscode内置图标
}
],
"menus": {
"view/title": [//标题后面的图标
{
"command": "calicoColors.clearColors",
"group": "navigation",
"when": "view == calicoColors.colorsView"//控制什么时机展示,对应上面的视图id
}
]
}
},
VS Code API
vscode
module
Parameter | Description |
---|---|
viewId: string | view的唯一id,需要匹配 contribution 里的views |
provider: WebviewViewProvider | webview 视图的提供者。provider是一个类的实例,这个类需要实现WebviewViewProvider接口(resolveWebviewView方法) |
public resolveWebviewView(
webviewView: vscode.WebviewView,
context: vscode.WebviewViewResolveContext,
_token: vscode.CancellationToken
) {
webviewView.webview.options = {
// Allow scripts in the webview
enableScripts: true,
localResourceRoots: [this._extensionUri],//限制资源访问路径
};
webviewView.webview.html = this._getHtmlForWebview(webviewView.webview);//设置webview内容
webviewView.webview.postMessage({ type: 'addColor' });//extension向webview发送消息
// 处理信息从extension到webview
//window.addEventListener('message', event => {
// const message = event.data; // The json data that the extension sent
// switch (message.type) {
// case 'addColor':
// {
// addColor();
// break;
// }
// }
// });
webviewView.webview.onDidReceiveMessage((data) => {//接受webview发送给extension的信息
switch (data.type) {
case 'colorSelected': {
vscode.window.activeTextEditor?.insertSnippet(
new vscode.SnippetString(`#${data.value}`)
);
break;
}
}
});
//webview里发送消息
// const vscode = acquireVsCodeApi();
// vscode.postMessage({ type: 'colorSelected', value: color });
}
webview里加载本地内容
Webview 在无法直接访问本地资源的隔离上下文中运行。这样做是出于安全原因。这意味着,为了从您的扩展加载图像、样式表和其他资源,或者从用户当前工作区加载任何内容,您必须使用该Webview.asWebviewUri
函数将本地 URI 转换file:
为 VS Code 可以用来加载的特殊 URI本地资源的子集。
private _getHtmlForWebview(webview: vscode.Webview) {
// Get the local path to main script run in the webview, then convert it to a uri we can use in the webview.
const scriptUri = webview.asWebviewUri(
vscode.Uri.joinPath(this._extensionUri, 'media', 'main.js')//对本地js文件的处理
);
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cat Colors</title>
</head>
<body>
<ul class="color-list">
</ul>
<button class="add-color-button">Add Color</button>
<script src="${scriptUri}"></script>
</body>
</html>`;
}
}
状态保存
当webview移动到后台又再次显示时,webview中的任何状态都将丢失。
在webview的js中我们可以使用vscode.getState()
和vscode.setState()
方法来保存和恢复JSON可序列化状态对象。当webview被隐藏时,即使webview内容本身被破坏,这些状态仍然会保存。当然了,当webview被销毁时,状态将被销毁。
//初始
const oldState = vscode.getState() || { colors: [] };
let colors = oldState.colors;
updateColorList(colors);
//有更新数据就保存一下
vscode.setState({ colors: colors });