1、我们在各种项目中都会碰到树形的视图,所以说这个还是很重要的。
2、项目中我们一般会用现成的组件(ant-design、element)来处理,这里我们使用自定义的方法,提供一个data来处理,比如这样:
最后喧染出来的效果类似如下:
3、定义一个自定义SFC,TreeItem.vue
<script setup>
import { ref, computed } from 'vue'
const props = defineProps({
model: Object
})
const isOpen = ref(false)
const isFolder = computed(() => {
return props.model.children && props.model.children.length
})
function toggle() {
isOpen.value = !isOpen.value
}
function changeType() {
if (!isFolder.value) {
props.model.children = []
addChild()
isOpen.value = true
}
}
function addChild() {
props.model.children.push({ name: 'new stuff' })
}
</script>
<template>
<li>
<div
:class="{ bold: isFolder }"
@click="toggle"
@dblclick="changeType">
{
{ model.name }}
<span v-if="isFolder">[{
{ isOpen ? '-' : '+' }}]</span>
</div>
<ul v-show="isOpen" v-if="isFolder">
<!--
一个可以通过其“name”选项递归渲染自己的组件,
(如果使用单文件组件,则从文件名推断)
-->
<TreeItem
class="item"
v-for="model in model.children"
:model="model">
</TreeItem>
<li class="add" @click="addChild">+</li>
</ul>
</li>
</template>
说明:
isFolder: 是一个计算型的属性,如果model的children不为空,并且这个children的length是大于0的,那么就会变成一个目录的形式,就是说下面有子项目。
isOpen:点击的时候,会切换isOpen的状态,对应的是template中的样式的变化,及“-”,“+”的变化,这样我们看上去就是展开的树形,或者是收缩状态的树形。
+:每一项的TreeItem的最后有一个+号,这样可以点击以后,在+号同级加入一项new stuff项。
ul:通过isOpen+isFolder来进行判断要不要显示子项目,如果都成立,那么就是利用自己TreeItem去递归出所有的子项目,并且如果还有,那么会直接children都显示完成。
这样就是我们使用子组件的优势了。
4、最后,我们建一个App.vue文件,来传递数据给TreeItem:
<!--
一个可以递归渲染自己的嵌套树组件。
你可以双击一个项目将其转变为一个文件夹。
-->
<script setup>
import { ref } from 'vue'
import TreeItem from './TreeItem.vue'
const treeData = ref({
name: 'My Tree',
children: [
{ name: 'hello' },
{ name: 'world' },
{
name: 'child folder',
children: [
{
name: 'child folder',
children: [{ name: 'hello' }, { name: 'world' }]
},
{ name: 'hello' },
{ name: 'world' },
{
name: 'child folder',
children: [{ name: 'hello' }, { name: 'world' }]
}
]
}
]
})
</script>
<template>
<ul>
<TreeItem class="item" :model="treeData"></TreeItem>
</ul>
</template>
<style>
.item {
cursor: pointer;
line-height: 1.5;
}
.bold {
font-weight: bold;
}
</style>
只要将属性model赋值,就可以达到树形的效果。
5、官方地址:https://cn.vuejs.org/examples/#tree
有兴趣可以自己尝试下,我想会有更大的收获。