「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」。
脚本和信息传递
webview跟iframe 一样同样是可以运行js 脚本的,但是在webview中默认是禁用的,在创建页面加上这个配置
//新创建webView
currentPanel = vscode.window.createWebviewPanel(
"start", // 只供内部使用,这个webview的标识
"start", // 给用户显示的面板标题
vscode.ViewColumn.One, // 给新的webview面板一个编辑器视图
{
enableScripts: true, // 启用JS,默认禁用
retainContextWhenHidden: true, // webview被隐藏时保持状态,避免被重置
localResourceRoots: [vscode.Uri.file(path.join(extensionPath, ""))],
}
);
在源码中我们修改 getWebview 方法,让咱们的冰墩墩出现奔跑的数字,当前只是演示,实践中酌情开启脚本
function getWebview(imgSrc) {
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<img src="${imgSrc}" />
<h1 id="count">0</h1>
<script>
const counter = document.getElementById('count');
let count = 0;
setInterval(() => {
counter.textContent = count++;
}, 100);
</script>
</body>
</html>`
}
看,数字跑的多快 but 虽然webveiw能做到任何普通页面脚本能做的到的事情,但是脚本不能直接使用vscode 提供的api
把插件信息传递给webView
插件可以调用 webview.postMessage()把数据发送到 它的webview,这个方法可以把json信息发送到webview中,在webview中使用messgae 接收事件 现在咱们实现一下,在 插件中注册时一个新命令把消息发给webview.webview接收信息展示在页面上
function getWebview(imgSrc) {
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<img src="${imgSrc}" />
<h1 id="count">0</h1>
<script>
const counter = document.getElementById('count');
let count = 0;
let timer = setInterval(() => {
counter.textContent = count++;
}, 100);
window.addEventListener('message', event => {
const message = event.data; // The JSON data our extension sent
counter.textContent = message.msg
clearInterval(timer)
});
</script>
</body>
</html>`;
}
context.subscriptions.push(
vscode.commands.registerCommand("z-ui.sendMsg", () => {
console.log(currentPanel);
if (!currentPanel) {
return;
}
// 把信息发送到webview
// 你可以发送任何序列化的JSON数据
currentPanel.webview.postMessage({ msg: "这是传递过来的信息" });
})
);
webView 把信息传递给插件
webView接收到插件发来的消息,webView接收到信息,发送信息给插件,完成一来一回
// 接收webView信息
currentPanel.webview.onDidReceiveMessage(
(message) => {
vscode.window.showInformationMessage(message.msg);
},
undefined,
context.subscriptions
);
安全性
每一个你创建的webview都必须遵循这些基础的安全性最佳实践,限制能力,如果webview不使用资源的话,localResourceRoots设置[]和[vscode.Uri.file(extensionContext.extensionPath)]