视图
视图是 VSCode 扩展的重要组成部分。VSCode 中有两种类型的视图:树视图和Webview。请阅读官方用户体验指南以获得基本了解。
在 Manifest 清单中定义
如官方文档所述,首先,你需要在 package.json
的 contributes.viewsContainers.[viewContainerType]
部分定义视图容器。然后你可以在 contributes.views.[viewContainerId]
部分定义你的视图。
json
{
"contributes": {
"viewsContainers": {
"activitybar": [
{
"id": "package-explorer",
"title": "Package Explorer",
"icon": "resources/package-explorer.svg"
}
]
},
"views": {
"package-explorer": [
{
"id": "package-dependencies",
"name": "Dependencies"
},
{
"id": "package-outline",
"name": "Outline"
}
]
}
}
}
注册树视图(TreeView)
树视图(TreeView)用于显示层级数据。你可以使用 useTreeView 函数定义树视图。
这里是一个树视图 (TreeView) 的示例:
ts
import type { TreeViewNode } from 'reactive-vscode'
import { computed, createSingletonComposable, useTreeView } from 'reactive-vscode'
import { TreeItemCollapsibleState } from 'vscode'
export const useDemoTreeView = createSingletonComposable(() => {
function getRootNode(index: number) {
return {
children: [
getChildNode(index * 10 + 1),
getChildNode(index * 10 + 2),
],
treeItem: {
label: `Root ${index}`,
collapsibleState: TreeItemCollapsibleState.Expanded,
},
}
}
function getChildNode(index: number) {
return {
treeItem: {
label: `Child ${index}`,
collapsibleState: TreeItemCollapsibleState.None,
},
}
}
const treeData = computed(() => {
const roots: TreeViewNode[] = []
for (let i = 1; i < 5; i++)
roots.push(getRootNode(i))
return roots
})
const view = useTreeView(
'reactive-tree-view',
treeData,
{
title: () => `Tree with ${treeData.value.length} roots`,
},
)
// return anything you want to expose
return view
})
然后你可以在任何地方调用 useDemoTreeView
函数来注册树视图并获取返回值:
ts
import { defineExtension } from 'reactive-vscode'
import { useDemoTreeView } from './treeView'
export = defineExtension(() => {
const demoTreeView = useDemoTreeView()
// ...
})
节点中的 children
属性用于定义节点的子节点。treeItem
属性是必需的,用于定义节点的树项。它应该是一个 TreeItem 对象,或者是一个解析为 TreeItem 对象的 Promise。
如果你想基于一些在 treeData
中未跟踪的响应式值触发更新,你可以将它们传递给 watchSource
选项。
关于 createSingletonComposable
createSingletonComposable 是一个用于创建单例组合式的辅助函数。它只会创建一次组合式,并在每次调用时返回相同的实例。WARNING
对于上面的示例,不应该在模块的顶层调用 useDemoTreeView
,因为此时扩展上下文不可用。相反,你应该始终在 setup
函数中调用它。
注册 Webview
Webview用于在编辑器中显示 Web 内容。你可以使用 useWebviewView 函数定义一个 webview。
这里是一个 webview 的示例:
ts
import { computed, createSingletonComposable, ref, useWebviewView } from 'reactive-vscode'
export const useDemoWebviewView = createSingletonComposable(() => {
const message = ref('')
const html = computed(() => `
<script>
vscode = acquireVsCodeApi()
function updateMessage() {
vscode.postMessage({
type: 'updateMessage',
message: document.querySelector('input').value,
})
}
</script>
<p>${message.value}</p>
<div style="display:flex; flex-wrap:wrap;">
<input type="text" placeholder="Input Message" />
<button onclick="updateMessage()">Update Message</button>
</div>
`)
const { postMessage } = useWebviewView(
'reactive-webview-view',
html,
{
webviewOptions: {
enableScripts: true,
enableCommandUris: true,
},
onDidReceiveMessage(ev) {
if (ev.type === 'updateMessage')
message.value = ev.message
},
},
)
return { message, postMessage }
})
调用 useDemoWebviewView
的时机与上一节中的树视图相同。
还有 useWebviewPanel 组合式用于创建 webview 面板。其用法与 useWebviewView 类似。