iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 12
0
Software Development

自己用的工具自己做! 30天玩轉VS Code Extension之旅系列 第 12

Day12 | 打造VSCode上的TreeView樹狀選單 (一) - 元件基本用法介紹

  • 分享至 

  • xImage
  •  

大家好,我是韋恩,今天是第十二天,讓我們來學習如何提供客製化樹狀選單的選項,讓使用者可以瀏覽大綱資訊,並點擊選單執行我們的命令服務。

今天一樣會有範例讓我們練習這些api,唯有動手練習才是熟悉它們的關鍵啊!

TreeView設定語法介紹


當我們在VSCode裡面使用TreeView API,和先前提的Context Menu一樣,需要先在Contribution Points裡註冊TreeView,讓我們來看一下註冊TreeView的json格式吧!

{
    ...
    "contributes": {
		"views": {
          "${選單元件位置}": [
               {
                "id": "${樹狀選單Id}",
                "name": "${樹狀選單名字}",
                "icon": "${選單Icon路徑}",
                "contextualTitle": "${樹狀選單標題}"
              }
          ]
        }
	},
    ...
}

首先,我們需要Views作為key值,並在下面的views物件裡設定對應的選單位置(如: explorer),並在選單位置屬性的array陣列裡面註冊點擊後觸發的選單物件設定。

大家還記得嗎?我們常用的檔案explorer的treeView是屬於sidebar的部分,點開sideBar裡面會有不同的View。現在我們要設定TreeView,就是在contributes裡面的views屬性裡設定它。views下面屬性跟Context Menu一樣需設定要呈現TreeView的選單位置,這裡我們透過自動補全,會看到預設有以下幾個位置可以貢獻。

  • explorer: SideBar上的Explorer View,我們平常查看專案各個檔案的選單。
  • scm: SideBar上的Source Control View,我們常用的Git管理功能就是在這個view上。
  • debug: SideBar上的Debug View,我們平常執行Run Extension的選單。
  • test: Test explorer view in the Side Bar,執行測試時VSCode預設的explorer。
  • remote: 新的功能,主要提供Remote功能的View選單,要透過extension api新增這裡的功能,需在package.json新增enableProposedApi : true的設定。

前面三個explorer、debug、scm的選單,分別對應到下圖ActivityBar的第一、第四、第三位置的Icon。

Test的icon是下圖第六個Icon,平常不會出現,需等執行測試才會出現。讀者們需到Run的選單上選取並執行Extension專案提供的Extension Tests選項執行測試,這時Text Explorer才會出現。

TreeView的Welcome content設定

當我們在Contribution Points時註冊Treeview,以下面設定為例:

{
    ...
    "contributes": {
		"views": {
			"explorer": [
				{
					"id": "day12TreeView",
					"name": "Day12TreeView"
				}
			]
		},
    }
    ...
}

我們會在explorer的sidebar上的最下方產生一個放置TreeView的元件。

此時我們沒有像VSCode提供TreeView的DataProvider設定與資料,因此會顯示一片空白。
VSCode針對這種情境,提供了Welcome content,讓我們可以在viewsWelcome屬性下面指定沒有跟VSCode註冊Tree的DataProvider的狀況,以下面範例為例:

{
    ...
    "contributes": {
		"viewsWelcome": [
			{
					"view": "day12TreeView",
					"contents": "Welcome to NewTreeView \n [learn more](https://code.visualstudio.com/api/extension-guides/tree-view/).\n[Resgister Data Provider](command:day12-treeview-practice.registerDataProvider)",
			}
        ],
    }
    ...
}

我們需先指定welcome內容的viewId(此處是剛才註冊的day12TreeView),再來,我們可以指定將顯示的內容,並且使用[LinkName](LinUrl)的markdown語法建立超連結,同時可以透過[ButtonName](CommandId)的語法顯示一個點擊後觸發命令的按鈕,結果如下:

好的,以上就是跟TreeView在Contribution Point的設定,接下來,我們將透過TreeView API來顯示對應的資料。API操作的部分,我們會用專案練習的方式一步一步介紹,讓我們開啟VSCode的Extension專案開始練習吧!

Day12練習:使用TreeView在explorer上吧!


環境準備

  • 使用yoman產生extension專案:
yo code
  • 依序輸入專案名稱、id等資訊

如果環境建立有問題,請再次參照之前的教學建立專案與環境喔!

專案範例配置

  • 專案Contribution Points命令配置:

讓我們照以下指示設定extension專案,首先於packagage.json,我們要在Contribution Points裡的View註冊TreeView跟相關Command,如下所示:

{
    ...
    "contributes": {
		"views": {
			"explorer": [
				{
					"id": "day12TreeView",
					"contextualTitle": "Day12-TreeViewTitle",
					"name": "Day12TreeView"
				}
			]
		},
		"viewsWelcome": [
			{
					"view": "day12TreeView",
					"contents": "Welcome to NewTreeView \n [learn more](https://code.visualstudio.com/api/extension-guides/tree-view/).\n[Resgister Data Provider](command:day12-treeview-practice.registerDataProvider)",
			}
        ],
		"commands": [
			{
				"command": "day12-treeview-practice.registerDataProvider",
				"title": "Day12: Register Treeview DataProvider"
			}
		]
	},
    ...
}

  • 專案activationEvents配置:

設置完Command後,我們一樣要在package.json配置activationEvents

{
    ...
    "activationEvents": [
		"*"
	],
    ...
}
  • 專案extension.ts範例程式配置:

import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {

	let disposable = vscode.commands.registerCommand('day12-treeview-practice.registerDataProvider', () => {
		vscode.window.showInformationMessage('Hello World from day12-treeview-practice!');
	});

	context.subscriptions.push(disposable);
}

export function deactivate() {}

請讀者照順序配置今天的vscode專案,接下來,我們要開始撰寫今天的TreeView邏輯了!

實作TreeViewDataProvider


在昨天的介紹裡,我已經提過我們需要先為TreeView提供一個DataProvider的class,並new出他的實例(instance)提供給register方法,因此先讓我們實作VSCode給定的Interface介面,如下所示:

從圖可以發現,vscode.TreeDataProvider雖然被實作,可是下面卻有紅色邱蚓狀的語法錯誤提示,讓我們把滑鼠移到發生錯誤的文字上。

可以看到,VSCode告訴我們這個vscode.TreeDataProvider需要提供一個泛型參數,在此處是vscode.TreeItem,因此也讓我們先繼承VSCode內建的TreeItem的class,並設定item的label屬性及點擊後觸發的command屬性等等,並將其類型提供給TreeDataProvider,如下所示:

現在換DataProvider下方出現紅色邱蚓狀的語法錯誤提示,因此再讓我們把鼠標移到錯誤文字上,點擊一下,再按⌘(command).,此時會觸發VSCode的Code Action,展開一個選單:

我們可以清楚看到,選單上面有一個Implement interface vscode.TreeDataProvider<TreeItem>的選項,請直接點擊下去,DataProvider的類別會自動產生需實作的方法的骨架。

有三個需實作的方法,分別是

TreeDataProvider方法 描述
getTreeItem 回傳TreeView呈現的TreeItem Element。
getChildren 回傳TreeView底下的treeItem們。
onDidChangeTreeData 回傳VSCode提供的EventEmitter的event監聽方法,通知DataProvider的訂閱者資料已經發生變化。

讓我們先實作getTreeItemgetChildren方法吧,如下所示:

class TreeViewItem extends vscode.TreeItem {
	constructor(label: string, collapsibleState?: vscode.TreeItemCollapsibleState) {
		super(label, collapsibleState);
	}
}

class DataProvider implements vscode.TreeDataProvider<TreeViewItem> {
	getTreeItem(element: TreeViewItem): vscode.TreeItem | Thenable<vscode.TreeItem> {
		return element;
	}
	getChildren(element?: TreeViewItem): vscode.ProviderResult<TreeViewItem[]> {
		return Promise.resolve([
			new TreeViewItem('TreeItem-01'),
			new TreeViewItem('TreeItem-02'),
			new TreeViewItem('TreeItem-03'),
		])
	}
}

export function activate(context: vscode.ExtensionContext) {
	let disposable = vscode.commands.registerCommand('day12-treeview-practice.registerDataProvider', () => {
		vscode.window.registerTreeDataProvider('day12TreeView', new DataProvider());
		vscode.window.showInformationMessage('Create day12-treeview!');
	});
	context.subscriptions.push(disposable);
}

export function deactivate() {}

好的,現在點擊UI上的Register按鈕,可以看到TreeView已經正確顯示。

結語


好啦,今天,我們創建了一個最基本的TreeView,並了解TreeView的使用方法。在範例裡,我們使用了大量typescript的繼承(extends)、介面(interface)實作(implement)等技巧,對初學者而言,確實需要不少typescript和javascript ES6的class語法知識才能順利掌握。如對範例有疑問或覺得難懂,請在下方留言給我,我會嘗試為您解答!

TreeView有更多的應用,明天我們會解析DataProvider的設計理念,並用開始實際的案例練習。

我們明天見,謝謝大家。

本日參考文件



上一篇
Day11 | 那些跟extension開發脫不了關係的window命名空間api
下一篇
Day13 | 打造VSCode上的TreeView樹狀選單 (二) - DataProvider的原理與相關觀念 X List的增刪改查
系列文
自己用的工具自己做! 30天玩轉VS Code Extension之旅36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言