本篇文章給大家介紹一下vscode中webview的使用方法。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有所幫助。
其實vscode也是基于electron框架的桌面軟件,也就是說,你在VSCode里看到的所有的界面本就是網(wǎng)頁。那在網(wǎng)頁里再顯示網(wǎng)頁怎么做?相信你也想到了,就是iframe。【推薦學習:《vscode》】
調(diào)試Webview
在VSCode命令面板中,輸入Open Webview Developer Tools 后可以打開Webview的控制臺
果然是iframe~
你的插件必須用Webview嗎?
官方英文文檔地址:https://code.visualstudio.com/api/extension-guides/webview
VSCode官方團隊希望插件開發(fā)者好好思考如下問題:
- 這個功能真的需要在VS Code中使用嗎?作為單獨的應用程序或網(wǎng)站會更好嗎?
- 使用Webview是實現(xiàn)功能的唯一方法嗎?您可以改用常規(guī)的VS Code API嗎?
創(chuàng)建WebviewPanel
const?panel?=?vscode.window.createWebviewPanel( ??'webview', ??"測試webview", ??vscode.ViewColumn.One ); panel.webview.html?=?`你好,我是Webview`
這樣就能創(chuàng)建一個Webview,渲染html內(nèi)容。
看上去使用很簡單對不對,但在實際使用Webview進行插件開發(fā)的過程中,還是遇到了不少坑的:
1號坑:使用本地資源
在VSCode中的Webview無法直接使用相對路徑的本地資源。比如下面這段代碼,我們引入了一個css,一個js,在body中有一張圖片。
直接這樣寫是無法加載到這些資源的
- 解決方法1
通過一個特殊的協(xié)議頭vscode-resource:資源文件絕對路徑,為了不影響咱們正常進行網(wǎng)頁開發(fā),我們可以封裝一個方法,從本地文件讀取html內(nèi)容,統(tǒng)一替換所有資源的路徑后再賦值給panel.webview.html
function?getWebViewContent(context,?templatePath)?{ const?resourcePath?=?path.join(context.extensionPath,?templatePath); const?dirPath?=?path.dirname(resourcePath); let?html?=?fs.readFileSync(resourcePath,?'utf-8'); ????html?=?html.replace(/(<link. if else return><p>這樣我們在開發(fā)網(wǎng)頁的時候就正常寫相對路徑就好了。</p> <p><img . alt="淺談VSCode中Webview的使用方法" ></img.></p> <p><img src="https://img.php.cn/upload/image/203/985/530/1623898128242935.gif" title="1623898128242935.gif" alt="7.gif"></p> <blockquote>注意事項:如果你使用Vue或者其他前端框架來進行插件Webview的開發(fā),就要注意資源的引入。以上封裝的方法只對頁面中hardcode的資源進行了替換。</blockquote> <ul><li>解決方法2</li></ul> <blockquote><p>使用iframe引入本地路徑html,不過VSCode的webview對iframe的限制也特別大,幾乎就是除了顯示網(wǎng)頁,和node環(huán)境交互就別想了。</p></blockquote> <h3 data-id="heading-5"><strong>2號坑:允許使用Javascript</strong></h3> <p>默認不支持Javascript</p> <ul><li>解決方法</li></ul> <p>添加option,將enableScritps設置為true,它的默認是false。</p> <p><img src="https://img.php.cn/upload/image/179/395/924/1623898135725239.gif" title="1623898135725239.gif" alt="8.gif"></p> <h3 data-id="heading-6"><strong>3號坑:cookie和localstorage</strong></h3> <p>cookie和localStorage可以用,但是!!!</p> <p>當VSCode重啟后,就全都清空了,所以等于不能用。</p> <ul><li>解決方法</li></ul> <p>調(diào)用VSCode的node環(huán)境來保存,這里需要讓webview和VSCode插件環(huán)境進行通訊。</p> <h3 data-id="heading-7"><strong>4號坑:Webview內(nèi)容被釋放</strong></h3> <p>當Webview所在的tab pannel進入后臺時(比如切到別的tab了),webview里的內(nèi)容就會被清除,內(nèi)存占用被釋放。再次切回時會重新加載html內(nèi)容。</p> <ul><li>解決辦法</li></ul> <p>啟用retainContextWhenHidden</p> <p><img src="https://img.php.cn/upload/image/918/668/404/1623898147614489.gif" title="1623898147614489.gif" alt="9.gif"></p> <h2><strong>消息通訊</strong></h2> <p><strong>1、插件發(fā)消息,Webview接收消息</strong></p> <ul><li>插件里的JS</li></ul> <pre class="brush:js;toolbar:false;">panel.webview.postMessage({text:?'你好,我是插件'});
- Webview里的JS
window.addEventListener('message',function(e){ ??console.log(e.data.text); })
2、Webview發(fā)消息,插件接收消息
- Webview里的JS
//初始化vscode插件api,沒什么特別的功能,主要就是postMessage var?vscode?=?acquireVsCodeApi(); vscode.postMessage({ ??text:?'你好,我是Webview' })
- 插件里的JS
panel.webview.onDidReceiveMessage(function(data)?{ ??console.log(data.text); });
比如前面提到的cookie和localstorage,就可以封裝一下消息通訊,通過插件node環(huán)境來保存到本地
var?vscode?=?acquireVsCodeApi(); function?setLocalStorage(k,v){ ??vscode.postMessage({ ????command:?'setLocalStorage', ????key:k, ????value:v ??}) }
panel.webview.onDidReceiveMessage(function(data)?{ ??if(data.command?==?'setLocalStorage'){ ????//使用lowdb ????lowdb.set(data.key,data.value).write(); ??} });
官方Demo
- https://github.com/microsoft/vscode-extension-samples/tree/master/webview-sample
- https://github.com/microsoft/vscode-extension-samples/tree/master/webview-view-sample
更多編程相關知識,請訪問:vscode!!