VsCode之使用WebView通信詳解
通過插件完成通信,這回我還是通過插件,只不過方式主要以在ts文件里面使用webview來進(jìn)行通信。
另外在此聲明,一定要好好看仔細(xì)看官方文檔,國內(nèi)關(guān)于VsCode相關(guān)的開發(fā),少之又少,雖然有一個叫小茗同學(xué)寫的相對較全面,但是大家可以仔細(xì)看,其實(shí)他的內(nèi)容大多也來自官方,同時有部分也加上自己的理解和想法。個人建議,關(guān)于VsCode插件相關(guān)的,最好是跑一跑VsCode相關(guān)官方例子,這樣有助于對VsCode插件開發(fā)有一個大致的思路和全局認(rèn)識,換言之有一個感性的認(rèn)識。
官方文檔地址:https://code.visualstudio.com/api
官方插件例子:https://github.com/Microsoft/vscode-extension-samples
引用官方的說明:
webview API允許擴(kuò)展在Visual Studio Code中創(chuàng)建完全可自定義的視圖。例如,內(nèi)置的Markdown擴(kuò)展程序使用Web視圖來呈現(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)大,并開辟了一系列全新的擴(kuò)展可能性。
官方對于是否應(yīng)該使用webview需要考慮這么幾個方面?
第一,這個功能真的需要存在于VsCode中嗎?作為單獨(dú)的APP或者網(wǎng)站是否會更好?
第二,webview是實(shí)現(xiàn)功能的唯一方法嗎?可以使用常規(guī) Vs Code API嗎?
第三,webview會增加足夠的用戶價值來證明其高資源成本嗎?
在我看來,如果是在VsCode內(nèi)部進(jìn)行增加webview,可能導(dǎo)致某種混亂或者不利的影響,還不如直接通過插件開發(fā)來進(jìn)行分離完成功能,這樣既解耦又對VsCode本身影響不會太大。
官方的Demo:https://github.com/Microsoft/vscode-extension-samples/blob/master/webview-sample
官方講解:https://code.visualstudio.com/api/extension-guides/webview
上面我說過跑官方的例子有助于更好的認(rèn)識,同時對于學(xué)習(xí)信心的提升也有很大的幫助,同時你可以在此基礎(chǔ)上改,從而讓你對其認(rèn)識更加深刻。
項(xiàng)目結(jié)構(gòu)(以項(xiàng)目結(jié)構(gòu)中的組成來講解)
目錄的作用分別如下:
.vscode 運(yùn)行所必須,同時也包括一些用戶區(qū)和工作區(qū)設(shè)置(注意,用戶區(qū)設(shè)置優(yōu)于工作區(qū)設(shè)置)
node_modules node.js的依賴庫
out 編譯輸出目錄(ts編譯成功會輸出對應(yīng)的js)
src 源文件所在目錄(主要是ts文件,當(dāng)然了也可能是ts,就看你插件開發(fā)時,選擇的是js還是ts)
.gitignore git提交時排除一些無關(guān)緊要的(java maven項(xiàng)目對于一些target文件中.class是沒必要提交到git倉庫的)
.vscodeignore
如圖所示:
我覺得它的作用和.gitignore是一樣的,之所以存在它,是因?yàn)橐乐?gitignore不生效的緣故吧(以之前項(xiàng)目開發(fā)經(jīng)歷來說,有的時候確實(shí)存在.gitignore無效問題)。
當(dāng)然了,這些源于我個人的看法,github上有關(guān)于這個的討論,感興趣的可以參考:https://github.com/Microsoft/vscode-vsce/issues/12
有不少外國開發(fā)者們在這里提自己的看法。
package-lock.json 通過這個是執(zhí)行npm install 產(chǎn)生的 package-lock.json顧名思義,主要的作用是鎖定安裝依賴的版本,保持版本一致性。
package.json 從node.js的角度來說它是一個模塊描述文件(包含安裝模塊所需的依賴聲明及其版本號、作者名、描述等。
以小茗同學(xué)的package.json來講解,這個文件里面的內(nèi)容作用分別為如下(大家可以做一個參考,實(shí)際情況根據(jù)需求而定):
{
// 插件的名字,應(yīng)全部小寫,不能有空格
"name": "vscode-plugin-demo",
// 插件的友好顯示名稱,用于顯示在應(yīng)用市場,支持中文
"displayName": "VSCode插件demo",
// 描述
"description": "VSCode插件demo集錦",
// 關(guān)鍵字,用于應(yīng)用市場搜索
"keywords": ["vscode", "plugin", "demo"],
// 版本號
"version": "1.0.0",
// 發(fā)布者,如果要發(fā)布到應(yīng)用市場的話,這個名字必須與發(fā)布者一致
"publisher": "sxei",
// 表示插件最低支持的vscode版本
"engines": {
"vscode": "^1.27.0"
},
// 插件應(yī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),整個插件最重要最多的配置項(xiàng)
"contributes": {
// 插件配置項(xiàng)
"configuration": {
"type": "object",
// 配置項(xiàng)標(biāo)題,會顯示在vscode的設(shè)置頁
"title": "vscode-plugin-demo",
"properties": {
// 這里我隨便寫了2個設(shè)置,配置你的昵稱
"vscodePluginDemo.yourName": {
"type": "string",
"default": "guest",
"description": "你的名字"
},
// 是否在啟動時顯示提示
"vscodePluginDemo.showTip": {
"type": "boolean",
"default": true,
"description": "是否在每次啟動時顯示歡迎提示!"
}
}
},
// 命令
"commands": [
{
"command": "extension.sayHello",
"title": "Hello World"
}
],
// 快捷鍵綁定
"keybindings": [
{
"command": "extension.sayHello",
"key": "ctrl+f10",
"mac": "cmd+f10",
"when": "editorTextFocus"
}
],
// 菜單
"menus": {
// 編輯器右鍵菜單
"editor/context": [
{
// 表示只有編輯器具有焦點(diǎn)時才會在菜單中出現(xiàn)
"when": "editorFocus",
"command": "extension.sayHello",
// navigation是一個永遠(yuǎn)置頂?shù)姆纸M,后面的@6是人工進(jìn)行組內(nèi)排序
"group": "navigation@6"
},
{
"when": "editorFocus",
"command": "extension.demo.getCurrentFilePath",
"group": "navigation@5"
},
{
// 只有編輯器具有焦點(diǎn),并且打開的是JS文件才會出現(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對應(yīng)
"beautifulGirl": [
{
"id": "beautifulGirl1",
"name": "國內(nèi)美女"
},
{
"id": "beautifulGirl2",
"name": "國外美女"
},
{
"id": "beautifulGirl3",
"name": "人妖"
}
]
},
// 圖標(biāo)主題
"iconThemes": [
{
"id": "testIconTheme",
"label": "測試圖標(biāo)主題",
"path": "./theme/icon-theme.json"
}
]
},
// 同 npm scripts
"scripts": {
"postinstall": "node ./node_modules/vscode/bin/install",
"test": "node ./node_modules/vscode/bin/test"
},
// 開發(fā)依賴
"devDependencies": {
"typescript": "^2.6.1",
"vscode": "^1.1.6",
"eslint": "^4.11.0",
"@types/node": "^7.0.43",
"@types/mocha": "^2.2.42"
},
// 后面這幾個應(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"
},
// 主頁
"homepage": "https://github.com/sxei/vscode-plugin-demo/blob/master/README.md"
}
目前我改寫的官方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"
}
}
兩者對比,后者更簡單。
注意:其中我主要改寫官方的這一部分
"activationEvents": [
"onCommand:extension.helloWorld",
"onCommand:extension.loginValidate"
],
"main": "./out/loginValidate",
"contributes": {
"commands": [
{
"command": "extension.helloWorld",
"title": "登錄"
},
{
"command": "extension.loginValidate",
"title": "登錄驗(yàn)證"
}
]
},
這一部分分別對應(yīng)extension.ts和loginValidate.ts,如下圖所示:
大家可以看到,其實(shí)兩者區(qū)別并不大,主要的差異還是registerCommand括號里面的。
有朋友也行會疑惑這個是什么意思不太明白。
registerCommand主要是注冊命令,這個注冊命令與圖中的一致:
保持一致的話,就能F5運(yùn)行插件項(xiàng)目打開一個新的窗口(可理解為是插件),通過快捷鍵ctrl+shift+p就可以看到如圖:
點(diǎn)擊這個登錄驗(yàn)證回車,即可出現(xiàn)如下webview視圖
對了還有一點(diǎn)要強(qiáng)調(diào)一下,目前有個小局限性就是不能命令有一定的限制,主要是因?yàn)檫@個地方:
由于指定該主函數(shù),所以只能對應(yīng)的loginValidate.js起作用,所以extension.js就不能起作用了,如果你要強(qiáng)行點(diǎn)擊登錄就會出現(xiàn)命令找不到,如圖所示:
tsconfig.json(關(guān)于它的詳解,可以參考這篇文章:https://www.jb51.net/article/161435.htm)
雖然有詳解不過我還是要說一下,如果一個目錄下存在一個tsconfig.json文件,那么它意味著這個目錄是TypeScript項(xiàng)目的根目錄。tsconfig.json文件中指定了用來編譯這個項(xiàng)目的根文件和編譯選項(xiàng)。
tslint.json 主要用于typescript的語法檢查
最后貼一下我的loginValidate.ts代碼(extension.ts代碼就不貼了,前面說到過它們的區(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" style="color:black;"/></p>
<p>密 碼 :<input type="password" id="password" style="color:black;"/></p>
<p> <input type="button" style="color:black;" 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,這個webview相當(dāng)于html,那么就可以在里面引用其它的前端組件來借此實(shí)現(xiàn)某個功能,但是請注意,可能會有一定的限制,比如不能使用alert這種彈框方式。
另外建議編寫webview的時候,特別是編寫里面的html,最好在外面編寫,直接使用瀏覽器運(yùn)行沒有問題,然后再嵌入進(jìn)去,這樣有助于排除一些不必要的錯誤,利于效率的提高。
今天寫到這吧,后面筆者會分享有關(guān)于vscode二次開發(fā)更多的知識。本次分享出來,希望能夠給小伙伴們帶來幫助。也希望大家多多支持我們。
上一篇:ASP.Net Core中使用枚舉類而不是枚舉的方法
欄 目:ASP.NET
本文標(biāo)題:VsCode之使用WebView通信詳解
本文地址:http://www.jygsgssxh.com/a1/ASP_NET/10921.html
您可能感興趣的文章
- 01-11vscode extension插件開發(fā)詳解
- 01-11VsCode插件開發(fā)之插件初步通信的方法步驟
- 01-11.NET Core 遷移躺坑記續(xù)集之Win下莫名其妙的超時
- 01-11ASP.NET Core靜態(tài)文件的使用方法
- 01-11.NET Core 3.0之創(chuàng)建基于Consul的Configuration擴(kuò)展組件
- 01-11ASP.Net Core中使用枚舉類而不是枚舉的方法
- 01-11使用dotnet-dump 查找 .net core 3.0 占用CPU 100%的原因解析
- 01-11WCF中使用nettcp協(xié)議進(jìn)行通訊的方法
- 01-11.NET Core 3.0中WPF使用IOC的圖文教程
- 01-11.Net項(xiàng)目中NLog的配置和使用實(shí)例詳解


閱讀排行
本欄相關(guān)
- 01-11vscode extension插件開發(fā)詳解
- 01-11VsCode插件開發(fā)之插件初步通信的方法
- 01-11如何給asp.net core寫個簡單的健康檢查
- 01-11.net core高吞吐遠(yuǎn)程方法如何調(diào)用組件
- 01-11淺析.Net Core中Json配置的自動更新
- 01-11.NET開發(fā)人員關(guān)于ML.NET的入門學(xué)習(xí)
- 01-11.NET Core 遷移躺坑記續(xù)集之Win下莫名其
- 01-11.net core webapi jwt 更為清爽的認(rèn)證詳解
- 01-11docker部署Asp.net core應(yīng)用的完整步驟
- 01-11ASP.NET Core靜態(tài)文件的使用方法
隨機(jī)閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 04-02jquery與jsp,用jquery
- 01-10delphi制作wav文件的方法
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個骰子


