VS Code插件开发教程--树视图+网页视图--完整demo+图--3

2,451 阅读4分钟

简介

你好!

本文定位为初次接触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) 方法中传递进来的。

这个方法只有在 webViewPanelundefined 时才执行。所以 ${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.~ 来读取数据。

接着修改 iframesrc 值。

很好了。接下来去测试下效果吧。

来个步骤:

1、修改 iframesrc

2、当 webviewPanel 存在时,添加 postMessage 事件

3、html 增加 addEventListener 监听事件,修改 iframesrc

七、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 带上不同的参数,就能够调用相同的监听事件了。

好啦~怎么样,有没有学到点东西呢?给个评价呗。

全部代码 都在这里拉。

在这里插入图片描述