溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

VsCode中使用WebView通信的示例

發(fā)布時(shí)間:2021-02-22 11:31:43 來(lái)源:億速云 閱讀:533 作者:清風(fēng) 欄目:開(kāi)發(fā)技術(shù)

本文將為大家詳細(xì)介紹“VsCode中使用WebView通信的示例”,內(nèi)容步驟清晰詳細(xì),細(xì)節(jié)處理妥當(dāng),而小編每天都會(huì)更新不同的知識(shí)點(diǎn),希望這篇“VsCode中使用WebView通信的示例”能夠給你意想不到的收獲,請(qǐng)大家跟著小編的思路慢慢深入,具體內(nèi)容如下,一起去收獲新知識(shí)吧。

vscode有什么用

Visual Studio Code 是一個(gè)運(yùn)行于 OS X,Windows和 Linux 之上的,針對(duì)于編寫(xiě)現(xiàn)代 web 和云應(yīng)用的跨平臺(tái)編輯器,它為開(kāi)發(fā)者們提供了對(duì)多種編程語(yǔ)言的內(nèi)置支持,并且正如 Microsoft 在Build 大會(huì)的 keynote 中所指出的,這款編輯器也會(huì)為這些語(yǔ)言都提供了豐富的代碼補(bǔ)全和導(dǎo)航功能。

之前我在這篇文章VsCode插件開(kāi)發(fā)之插件初步通信

通過(guò)插件完成通信,這回我還是通過(guò)插件,只不過(guò)方式主要以在ts文件里面使用webview來(lái)進(jìn)行通信。

另外在此聲明,一定要好好看仔細(xì)看官方文檔,國(guó)內(nèi)關(guān)于VsCode相關(guān)的開(kāi)發(fā),少之又少,雖然有一個(gè)叫小茗同學(xué)寫(xiě)的相對(duì)較全面,但是大家可以仔細(xì)看,其實(shí)他的內(nèi)容大多也來(lái)自官方,同時(shí)有部分也加上自己的理解和想法。個(gè)人建議,關(guān)于VsCode插件相關(guān)的,最好是跑一跑VsCode相關(guān)官方例子,這樣有助于對(duì)VsCode插件開(kāi)發(fā)有一個(gè)大致的思路和全局認(rèn)識(shí),換言之有一個(gè)感性的認(rèn)識(shí)。

官方文檔地址:https://code.visualstudio.com/api

官方插件例子:https://github.com/Microsoft/vscode-extension-samples

引用官方的說(shuō)明:

webview API允許擴(kuò)展在Visual Studio Code中創(chuàng)建完全可自定義的視圖。例如,內(nèi)置的Markdown擴(kuò)展程序使用Web視圖來(lái)呈現(xiàn)Markdown預(yù)覽。Web視圖還可用于構(gòu)建復(fù)雜的用戶界面,超出VsCode的本機(jī)API支持。

將webview視為iframe擴(kuò)展程序控制的Vs代碼內(nèi)部。webview幾乎可以呈現(xiàn)此框架中的任何HTML內(nèi)容,并使用消息傳遞與擴(kuò)展進(jìn)行通信。這種自由使得webview非常強(qiáng)大,并開(kāi)辟了一系列全新的擴(kuò)展可能性。

官方對(duì)于是否應(yīng)該使用webview需要考慮這么幾個(gè)方面?

第一,這個(gè)功能真的需要存在于VsCode中嗎?作為單獨(dú)的APP或者網(wǎng)站是否會(huì)更好?

第二,webview是實(shí)現(xiàn)功能的唯一方法嗎?可以使用常規(guī) Vs Code API嗎?

第三,webview會(huì)增加足夠的用戶價(jià)值來(lái)證明其高資源成本嗎?

在我看來(lái),如果是在VsCode內(nèi)部進(jìn)行增加webview,可能導(dǎo)致某種混亂或者不利的影響,還不如直接通過(guò)插件開(kāi)發(fā)來(lái)進(jìn)行分離完成功能,這樣既解耦又對(duì)VsCode本身影響不會(huì)太大。

官方的Demo:https://github.com/Microsoft/vscode-extension-samples/blob/master/webview-sample

官方講解:https://code.visualstudio.com/api/extension-guides/webview

上面我說(shuō)過(guò)跑官方的例子有助于更好的認(rèn)識(shí),同時(shí)對(duì)于學(xué)習(xí)信心的提升也有很大的幫助,同時(shí)你可以在此基礎(chǔ)上改,從而讓你對(duì)其認(rèn)識(shí)更加深刻。

項(xiàng)目結(jié)構(gòu)(以項(xiàng)目結(jié)構(gòu)中的組成來(lái)講解)

VsCode中使用WebView通信的示例

目錄的作用分別如下:

.vscode 運(yùn)行所必須,同時(shí)也包括一些用戶區(qū)和工作區(qū)設(shè)置(注意,用戶區(qū)設(shè)置優(yōu)于工作區(qū)設(shè)置)

node_modules node.js的依賴庫(kù)

out 編譯輸出目錄(ts編譯成功會(huì)輸出對(duì)應(yīng)的js)

src 源文件所在目錄(主要是ts文件,當(dāng)然了也可能是ts,就看你插件開(kāi)發(fā)時(shí),選擇的是js還是ts)

.gitignore git提交時(shí)排除一些無(wú)關(guān)緊要的(java maven項(xiàng)目對(duì)于一些target文件中.class是沒(méi)必要提交到git倉(cāng)庫(kù)的)

.vscodeignore

如圖所示:

VsCode中使用WebView通信的示例

我覺(jué)得它的作用和.gitignore是一樣的,之所以存在它,是因?yàn)橐乐?gitignore不生效的緣故吧(以之前項(xiàng)目開(kāi)發(fā)經(jīng)歷來(lái)說(shuō),有的時(shí)候確實(shí)存在.gitignore無(wú)效問(wèn)題)。

當(dāng)然了,這些源于我個(gè)人的看法,github上有關(guān)于這個(gè)的討論,感興趣的可以參考:https://github.com/Microsoft/vscode-vsce/issues/12

有不少外國(guó)開(kāi)發(fā)者們?cè)谶@里提自己的看法。

package-lock.json 通過(guò)這個(gè)是執(zhí)行npm install 產(chǎn)生的 package-lock.json顧名思義,主要的作用是鎖定安裝依賴的版本,保持版本一致性。

package.json 從node.js的角度來(lái)說(shuō)它是一個(gè)模塊描述文件(包含安裝模塊所需的依賴聲明及其版本號(hào)、作者名、描述等。

以小茗同學(xué)的package.json來(lái)講解,這個(gè)文件里面的內(nèi)容作用分別為如下(大家可以做一個(gè)參考,實(shí)際情況根據(jù)需求而定):

{
  // 插件的名字,應(yīng)全部小寫(xiě),不能有空格
  "name": "vscode-plugin-demo",
  // 插件的友好顯示名稱,用于顯示在應(yīng)用市場(chǎng),支持中文
  "displayName": "VSCode插件demo",
  // 描述
  "description": "VSCode插件demo集錦",
  // 關(guān)鍵字,用于應(yīng)用市場(chǎng)搜索
  "keywords": ["vscode", "plugin", "demo"],
  // 版本號(hào)
  "version": "1.0.0",
  // 發(fā)布者,如果要發(fā)布到應(yīng)用市場(chǎng)的話,這個(gè)名字必須與發(fā)布者一致
  "publisher": "sxei",
  // 表示插件最低支持的vscode版本
  "engines": {
    "vscode": "^1.27.0"
  },
  // 插件應(yīng)用市場(chǎng)分類,可選值: [Programming Languages, Snippets, Linters, Themes, Debuggers, Formatters, Keymaps, SCM Providers, Other, Extension Packs, Language Packs]
  "categories": [
    "Other"
  ],
  // 插件圖標(biāo),至少128x128像素
  "icon": "images/icon.png",
  // 擴(kuò)展的激活事件數(shù)組,可以被哪些事件激活擴(kuò)展,后文有詳細(xì)介紹
  "activationEvents": [
    "onCommand:extension.sayHello"
  ],
  // 插件的主入口
  "main": "./src/extension",
  // 貢獻(xiàn)點(diǎn),整個(gè)插件最重要最多的配置項(xiàng)
  "contributes": {
    // 插件配置項(xiàng)
    "configuration": {
      "type": "object",
      // 配置項(xiàng)標(biāo)題,會(huì)顯示在vscode的設(shè)置頁(yè)
      "title": "vscode-plugin-demo",
      "properties": {
        // 這里我隨便寫(xiě)了2個(gè)設(shè)置,配置你的昵稱
        "vscodePluginDemo.yourName": {
          "type": "string",
          "default": "guest",
          "description": "你的名字"
        },
        // 是否在啟動(dòng)時(shí)顯示提示
        "vscodePluginDemo.showTip": {
          "type": "boolean",
          "default": true,
          "description": "是否在每次啟動(dòng)時(shí)顯示歡迎提示!"
        }
      }
    },
    // 命令
    "commands": [
      {
        "command": "extension.sayHello",
        "title": "Hello World"
      }
    ],
    // 快捷鍵綁定
    "keybindings": [
      {
        "command": "extension.sayHello",
        "key": "ctrl+f10",
        "mac": "cmd+f10",
        "when": "editorTextFocus"
      }
    ],
    // 菜單
    "menus": {
      // 編輯器右鍵菜單
      "editor/context": [
        {
          // 表示只有編輯器具有焦點(diǎn)時(shí)才會(huì)在菜單中出現(xiàn)
          "when": "editorFocus",
          "command": "extension.sayHello",
          // navigation是一個(gè)永遠(yuǎn)置頂?shù)姆纸M,后面的@6是人工進(jìn)行組內(nèi)排序
          "group": "navigation@6"
        },
        {
          "when": "editorFocus",
          "command": "extension.demo.getCurrentFilePath",
          "group": "navigation@5"
        },
        {
          // 只有編輯器具有焦點(diǎn),并且打開(kāi)的是JS文件才會(huì)出現(xiàn)
          "when": "editorFocus && resourceLangId == javascript",
          "command": "extension.demo.testMenuShow",
          "group": "z_commands"
        },
        {
          "command": "extension.demo.openWebview",
          "group": "navigation"
        }
      ],
      // 編輯器右上角圖標(biāo),不配置圖片就顯示文字
      "editor/title": [
        {
          "when": "editorFocus && resourceLangId == javascript",
          "command": "extension.demo.testMenuShow",
          "group": "navigation"
        }
      ],
      // 編輯器標(biāo)題右鍵菜單
      "editor/title/context": [
        {
          "when": "resourceLangId == javascript",
          "command": "extension.demo.testMenuShow",
          "group": "navigation"
        }
      ],
      // 資源管理器右鍵菜單
      "explorer/context": [
        {
          "command": "extension.demo.getCurrentFilePath",
          "group": "navigation"
        },
        {
          "command": "extension.demo.openWebview",
          "group": "navigation"
        }
      ]
    },
    // 代碼片段
    "snippets": [
      {
        "language": "javascript",
        "path": "./snippets/javascript.json"
      },
      {
        "language": "html",
        "path": "./snippets/html.json"
      }
    ],
    // 自定義新的activitybar圖標(biāo),也就是左側(cè)側(cè)邊欄大的圖標(biāo)
    "viewsContainers": {
      "activitybar": [
        {
          "id": "beautifulGirl",
          "title": "美女",
          "icon": "images/beautifulGirl.svg"
        }
      ]
    },
    // 自定義側(cè)邊欄內(nèi)view的實(shí)現(xiàn)
    "views": {
      // 和 viewsContainers 的id對(duì)應(yīng)
      "beautifulGirl": [
        {
          "id": "beautifulGirl1",
          "name": "國(guó)內(nèi)美女"
        },
        {
          "id": "beautifulGirl2",
          "name": "國(guó)外美女"
        },
        {
          "id": "beautifulGirl3",
          "name": "人妖"
        }
      ]
    },
    // 圖標(biāo)主題
    "iconThemes": [
      {
        "id": "testIconTheme",
        "label": "測(cè)試圖標(biāo)主題",
        "path": "./theme/icon-theme.json"
      }
    ]
  },
  // 同 npm scripts
  "scripts": {
    "postinstall": "node ./node_modules/vscode/bin/install",
    "test": "node ./node_modules/vscode/bin/test"
  },
  // 開(kāi)發(fā)依賴
  "devDependencies": {
    "typescript": "^2.6.1",
    "vscode": "^1.1.6",
    "eslint": "^4.11.0",
    "@types/node": "^7.0.43",
    "@types/mocha": "^2.2.42"
  },
  // 后面這幾個(gè)應(yīng)該不用介紹了
  "license": "SEE LICENSE IN LICENSE.txt",
  "bugs": {
    "url": "https://github.com/sxei/vscode-plugin-demo/issues"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/sxei/vscode-plugin-demo"
  },
  // 主頁(yè)
  "homepage": "https://github.com/sxei/vscode-plugin-demo/blob/master/README.md"
}

目前我改寫(xiě)的官方demo的package.json文件為如下:

{
  "name": "helloworld",
  "displayName": "HelloWorld",
  "description": "",
  "version": "0.0.1",
  "engines": {
    "vscode": "^1.30.0"
  },
  "categories": [
    "Other"
  ],
  "activationEvents": [
    "onCommand:extension.helloWorld",
    "onCommand:extension.loginValidate"
  ],
  "main": "./out/loginValidate",
  "contributes": {
    "commands": [
      {
        "command": "extension.helloWorld",
        "title": "登錄"
      },
      {
        "command": "extension.loginValidate",
        "title": "登錄驗(yàn)證"
      }
    ]
  },
  "scripts": {
    "vscode:prepublish": "npm run compile",
    "compile": "tsc -p ./",
    "watch": "tsc -watch -p ./",
    "postinstall": "node ./node_modules/vscode/bin/install",
    "test": "npm run compile && node ./node_modules/vscode/bin/test"
  },
  "devDependencies": {
    "typescript": "^3.1.4",
    "vscode": "^1.1.25",
    "tslint": "^5.8.0",
    "@types/node": "^8.10.25",
    "@types/mocha": "^2.2.42"
  }
}

兩者對(duì)比,后者更簡(jiǎn)單。

注意:其中我主要改寫(xiě)官方的這一部分

"activationEvents": [
    "onCommand:extension.helloWorld",
    "onCommand:extension.loginValidate"
  ],
  "main": "./out/loginValidate",
  "contributes": {
    "commands": [
      {
        "command": "extension.helloWorld",
        "title": "登錄"
      },
      {
        "command": "extension.loginValidate",
        "title": "登錄驗(yàn)證"
      }
    ]
  },

這一部分分別對(duì)應(yīng)extension.ts和loginValidate.ts,如下圖所示:

VsCode中使用WebView通信的示例

VsCode中使用WebView通信的示例

大家可以看到,其實(shí)兩者區(qū)別并不大,主要的差異還是registerCommand括號(hào)里面的。

有朋友也行會(huì)疑惑這個(gè)是什么意思不太明白。

registerCommand主要是注冊(cè)命令,這個(gè)注冊(cè)命令與圖中的一致:

VsCode中使用WebView通信的示例

保持一致的話,就能F5運(yùn)行插件項(xiàng)目打開(kāi)一個(gè)新的窗口(可理解為是插件),通過(guò)快捷鍵ctrl+shift+p就可以看到如圖:

VsCode中使用WebView通信的示例

點(diǎn)擊這個(gè)登錄驗(yàn)證回車,即可出現(xiàn)如下webview視圖

VsCode中使用WebView通信的示例

對(duì)了還有一點(diǎn)要強(qiáng)調(diào)一下,目前有個(gè)小局限性就是不能命令有一定的限制,主要是因?yàn)檫@個(gè)地方:

VsCode中使用WebView通信的示例

由于指定該主函數(shù),所以只能對(duì)應(yīng)的loginValidate.js起作用,所以extension.js就不能起作用了,如果你要強(qiáng)行點(diǎn)擊登錄就會(huì)出現(xiàn)命令找不到,如圖所示:

VsCode中使用WebView通信的示例

tsconfig.json(關(guān)于它的詳解,可以參考這篇文章:https://www.jb51.net/article/161435.htm)

雖然有詳解不過(guò)我還是要說(shuō)一下,如果一個(gè)目錄下存在一個(gè)tsconfig.json文件,那么它意味著這個(gè)目錄是TypeScript項(xiàng)目的根目錄。tsconfig.json文件中指定了用來(lái)編譯這個(gè)項(xiàng)目的根文件和編譯選項(xiàng)。

tslint.json 主要用于typescript的語(yǔ)法檢查

最后貼一下我的loginValidate.ts代碼(extension.ts代碼就不貼了,前面說(shuō)到過(guò)它們的區(qū)別,基本上是大同小異):

loginValidate.ts

// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {

  // Use the console to output diagnostic information (console.log) and errors (console.error)
  // This line of code will only be executed once when your extension is activated
    console.log('Congratulations, your extension "loginValidate" is now active!');

  // The command has been defined in the package.json file
  // Now provide the implementation of the command with registerCommand
  // The commandId parameter must match the command field in package.json
  let disposable = vscode.commands.registerCommand('extension.loginValidate', () => {
    // The code you place here will be executed every time your command is executed

    // Display a message box to the user
    const panel = vscode.window.createWebviewPanel(
      'catCoding',
      'Login Validate',
      vscode.ViewColumn.One,
      {
        // Enable scripts in the webview
        enableScripts: true
      }
    );

    panel.webview.html = getWebviewContent();
  });

  context.subscriptions.push(disposable);
}

// this method is called when your extension is deactivated
export function deactivate() {}
function getWebviewContent() {
  return `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>登錄</title>
</head>
<body>
<div id="form">
<form id="login">
  <p>用戶名:<input type="text" id="userName" /></p>
  <p>密&nbsp;&nbsp;碼&nbsp;&nbsp;:<input type="password" id="password" /></p>
  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="button"  value="提交" onclick="test()"/>

</form>
<div id="register">
<input type="button" value="退出" onclick="exits()"/>
</div>
</div>
 <script>
 function test(){
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function () {
  if (xhr.readyState == 4) {
  if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
  console.log(xhr.responseText);
  $("#login).hide();
  } else {
  console.log(xhr.responseText);
  }
  }
  };
  xhr.open("POST", "http://localhost:8080/test-web/sysUser/queryUserCodeByInfo?userCode=2", true);
  xhr.send(null);      
} 

function exits(){
  
 $("#login").show();

}

 </script>
</body>
</html>`;
}

另外關(guān)于通信方面的,目前可以在此使用原生javascript的ajax,這個(gè)webview相當(dāng)于html,那么就可以在里面引用其它的前端組件來(lái)借此實(shí)現(xiàn)某個(gè)功能,但是請(qǐng)注意,可能會(huì)有一定的限制,比如不能使用alert這種彈框方式。

另外建議編寫(xiě)webview的時(shí)候,特別是編寫(xiě)里面的html,最好在外面編寫(xiě),直接使用瀏覽器運(yùn)行沒(méi)有問(wèn)題,然后再嵌入進(jìn)去,這樣有助于排除一些不必要的錯(cuò)誤,利于效率的提高。

如果你能讀到這里,小編希望你對(duì)“VsCode中使用WebView通信的示例”這一關(guān)鍵問(wèn)題有了從實(shí)踐層面最深刻的體會(huì),具體使用情況還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想閱讀更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI