简介
你好!
本文定位为初次接触vs code插件开发的小伙伴,开始有详细的教程如何一步一步的运用基础的插件开发
接下来会用完成的 demo 教大家 treeView 和 webView 的初级完成开发流程。小伙伴耐心跟着代码敲一遍能学会的哈。
先给小伙伴们看一下本文的目录架构:
- 一、介绍
- 二、安装
- 三、初识 VS code 插件 demo
- 四、treeView: 重识 package.json
- 五、treeView: 在视图中显示想要的 item
- 六、创建 webView 并嵌入百度页面
- 七、不同 item 显示不同的页面(数据传递: VS code -> html)
- 八、iframe 页面的数据传递指 VS code(iframe -> html -> vscode)
此文章为第三部分,如需从头开始阅读,请移步第一部分 或 第二部分
六、不同 item 显示不同的页面(数据传递: VS code -> html)
现在我们可以起一个 React 或者 Alita 项目
创建好3个页面,命名分别为 pig1, pig2, pig3。当然你要随意命名也可以,只不过这样子会比较方便。

那么接下来启动 React 或者 Alita 项目。
修改 WebView.ts 文件下的内容
<iframe id='iframe1' class="iframeDiv" src="http://localhost:8000/#/${label}" scrolling="auto"></iframe>
把 iframe 路径改成项目路径。
那么现在去启动一下插件吧。
是不是发现了一个问题,webView 只展示第一次选中的项,当你切换其他项时,路径并没有改变。这是为什么呢?
因为这里的参数 ${label} 是从 getIframeHtml(label) 方法中传递进来的。
这个方法只有在 webViewPanel 为 undefined 时才执行。所以 ${label} 永远都是创建 webView 时传递进来的参数。
那么现在有没有什么办法将点击事件的参数传递进 html 页面呢?有的。
介绍一个重要的方法:
postMessage(message): 将消息发布到webview内容。仅当Webview可见时才会传递消息。
接下来我们将继续修改 WebView.ts 文件
...//此处省略重复代码
if(webviewPanel === undefined) {
... //此处省略重复代码
webviewPanel.webview.html = getIframeHtml(label);
} else {
webviewPanel.title = label;
// 补上下面这句话
// 作用: 向 html 传递一个 标签为 label 的 Message
webviewPanel.webview.postMessage({label: label});
webviewPanel.reveal();
}
... //此处省略重复代码
export function getIframeHtml(label: string) {
return `
<head>
<style>
... 此处省略重复代码
</style>
<script>
window.addEventListener('message', (e) => {
document.getElementById('iframe1').src = 'http://localhost:8000/#/'+e.data.label+'/';
})
</script>
</head>
`
}
讲解一下上面 getIframeHtml() 方法中新增的代码:
window.addEventListener('message',(e) => {}): 监听事件,可以通过 e.data.~ 来读取数据。
接着修改 iframe 的 src 值。
很好了。接下来去测试下效果吧。
来个步骤:
1、修改 iframe 的src
2、当 webviewPanel 存在时,添加 postMessage 事件
3、html 增加 addEventListener 监听事件,修改 iframe 的src
七、iframe 页面的数据传递指 VS code(iframe -> html -> vscode)
还记得 iframe 页面中都有一个 Button 的按钮嘛?新增一个点击事件。
... // 省略重复代码
btnClick = () => {
// 向父页面传递 ifarmeLabel 标签的 Message 消息
// '*' 为任意的路径都可以 你也可以在 '' 中放入指定的 url
window.parent.postMessage({ifarmeLabel: 'pig1'},'*');
}
render() {
return (
<div>
<h2>this is pig1</h2>
<Button onClick={this.btnClick}>showMessage:pig1</Button>
</div>
);
}
... // 省略重复代码
接下来我们去 WebView.ts 页面的 html 里监听和接收 ifarmeLabel 的数据。
<script>
// 导入 vscode 我们需要通过 vscode 来向 vscode 发送消息
const vscode = acquireVsCodeApi();
// 稍微修改下监听事件的代码
window.addEventListener('message', (e) => {
// 当 label 存在时 切换 iframe 页面
if(e.data.label) {
document.getElementById('iframe1').src = 'http://localhost:8000/#/'+e.data.label+'/';
}
// 当监听到 ifarmeLabel 存在时,向 vscode 发送消息
if(e.data.ifarmeLabel) {
// 我们可以先看看数据有没有传递过来
console.log(e.data.ifarmeLabel);
// 这里就是向 vscode 发送信息 command:一个标识, text:参数的传递
vscode.postMessage({
command: 'ifarmeLabel',
text: e.data.ifarmeLabel+'',
})
}
})
</script>
有需要看上面 console.log(e.data.ifarmeLabel) 的小伙伴可以看下面的操作打开 切换开发人员工具。
点击 Button 按钮。看看是否有输出我们要的数据。

通过上面的代码,我们也已经向 VS code 传递了 command 标识和 text 参数。
接下来就是在 vscode 监听并接收数据。
先来认识一下 onDidReceiveMessage() 方法:当 webview 内容发布消息时触发。
还是继续编辑 WebView.ts 文件
export function createWebView(
context: ExtensionContext,
viewColumn: ViewColumn,
label: string
) {
if(webviewPanel === undefined) {...} else {...}
webviewPanel.onDidDispose(() => {webviewPanel = undefined;});
// 当 html 传递参数时,onDidReceiveMessage 可以监听到消息
// message: 为传递过来的参数
webviewPanel.webview.onDidReceiveMessage(message => {
switch(message.command) {
case 'ifarmeLabel':
window.showInformationMessage(message.text);
}
});
return webviewPanel;
}
好了。测试下效果吧,是不是如下图所展示的呢?

那么其他两个网页的的按钮点击事件,只要传递相同的标识 ifarmeLabel 带上不同的参数,就能够调用相同的监听事件了。
好啦~怎么样,有没有学到点东西呢?给个评价呗。
全部代码 都在这里拉。
