BLOG
ブログ
2023/10/24
技術系
【Vue】Vue-3-Treeviewでツリービューを表示する
タグ
Vuetify 3でv-treeview
が使えなくなっていたので、代わりにVue-3-Treeviewというライブラリを使ってみました。
動作環境
- Vue: 3.2.41
- vue3-treeview: 0.4.1
導入
公式サイトに従ってインストールします。
npm install vue3-treeview
使用例
ツリービューを表示する
今回はチェックボックスを表示したかったのでconfig
に設定します。
配列のkeyがidに、text
が表示名になります。children
に子階層のkeyを指定します。
<script setup>
import 'vue3-treeview/dist/style.css';
import Tree from 'vue3-treeview';
import { ref, reactive } from 'vue';
const config = ref({
roots: ["id1", "id2"], // 第一階層のkey
checkboxes: true, // チェックボックスあり
checkMode: 0, // 親階層をチェックした際に子階層もチェックする
padding: 22,
});
const nodes = reactive({
id1: {
text: "text1",
children: ["id11", "id12"],
state: {
opened: true, // デフォルトで開く
}
},
id11: {
text: "text1-1",
children: [],
},
id12: {
text: "text1-2",
children: [],
},
id2: {
text: "text2",
children: ["id21"],
},
id21: {
text: "text2-1",
children: ["id211"],
},
id211: {
text: "text2-1-1",
children: [],
},
});
</script>
<template>
<Tree :config="config" :nodes="nodes"></Tree>
</template>
チェックした値を取得する
残念ながら、v-model
でチェックしたidのリストを取得することはできませんでした。
- チェックすると元データ
nodes
のstate.checked
が変わる - 親階層をチェックしても子階層の
state.checked
は変わらない
以上を踏まえて対応し、チェックしたidを取得できるようにしました。
<script setup>
(省略)
const checked = ref([]);
const nodes = reactive({
id1: {
text: "text1",
children: ["id11", "id12"],
state: {
opened: true,
checked: false, // state.checkedのデフォルト値をセットしておく
}
},
(省略)
id211: {
text: "text2-1-1",
children: [],
state: { checked: false }
},
});
const getChecked = (node) => {
// 親階層のcheckedを子階層に反映
for (const key in node.children) {
let id = node.children[key];
nodes[id].state.checked = node.state.checked;
}
checked.value = [];
for (const key in nodes) {
if (nodes[key].children.length === 0) {
if (nodes[key].state.checked) {
checked.value.push(key);
}
}
}
}
</script>
<template>
<Tree
:config="config"
:nodes="nodes"
@nodeChecked="getChecked"
@nodeUnchecked="getChecked"
>
</Tree>
{{ checked }}
</template>
文字をクリックしてチェックできるようにする
デフォルトではチェックボックス自体をクリックしなければチェックされないので、文字の部分もクリックできるようにしました。text
を空にして、after-inputスロットでbuttonを表示しています。
<script setup>
(省略)
const nodes = reactive({
id1: {
id: "id1", // idを追加
text: "", // textは空にする
name: "text1",
children: ["id11", "id12"],
state: {
opened: true,
checked: false,
}
},
(省略)
id211: {
id: "id211",
text: "",
name: "text2-1-1",
children: [],
state: { checked: false }
},
});
const getChecked = (node) => {
(省略)
}
const clickText = (node) => {
nodes[node.id].state.checked = !node.state.checked;
getChecked(node);
}
</script>
<template>
<Tree
:config="config"
:nodes="nodes"
@nodeChecked="getChecked"
@nodeUnchecked="getChecked"
>
<template #after-input="item">
<button @click="clickText(item.node)">{{ item.node.name }}</button>
</template>
</Tree>
</template>
構造を理解するのに少し戸惑いましたが、気軽に使うことができて良かったです。
もしUIフレームワークに頼らずツリービューを実現したいようなケースがあれば、参考になれば幸いです。
株式会社ウイングドアは福岡のシステム開発会社です。
現在、私達と一緒に"楽しく仕事が出来る仲間"として、新卒・中途採用を絶賛募集しています!
ウイングドアの仲間達となら楽しく仕事できるかも?と興味をもった方、
お気軽にお問い合わせ下さい!