一个可以通过其“name”选项递归渲染自己的组件,(如果使用单文件组件,则从文件名推断)
下面的代码都是从官网复制的,我只是单纯记录一下这个用法。官网地址
封装组件
<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>
使用
<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>
实现效果:
展开