Vue树形组件是一个非常常用的组件,可以用于展示数据的层级结构,比如树形菜单、文件目录树等等。在Vue框架中,有很多非常好用的树形组件库,比如element-ui、iview、vue-treeselect等等,本文将主要介绍基于vue组件开发的树形组件。
一、懒加载
当有大量的节点需要渲染时,我们可以采用懒加载的方式来优化性能。我们可以只渲染目前可视范围内的节点,当用户需要展开某一个节点时再渲染其子节点。这种方式可以充分利用虚拟列表技术来减小渲染开销,提高组件的渲染性能。
// 自定义一个树形节点组件
<template>
<div :style="{ marginLeft: level * 20 + 'px' }">
<i v-if="isFolder" :class="{ open: open, close: !open }" @click="toggle"></i>
<span>{{ name }}</span>
</div>
</template>
// 通过watch监听是否需要懒加载子节点
watch: {
open(val) {
if (val) {
// 模拟异步加载子节点
setTimeout(() => {
this.children = [
{ name: '子节点1', isFolder: false },
{ name: '子节点2', isFolder: false },
{ name: '子节点3', isFolder: false }
]
}, 1000)
}
}
}
二、树形菜单
树形菜单是一种很常用的树形组件,往往用于网站的导航菜单等场景。我们可以通过遍历数据源来手动构建一个树形菜单组件。
<template>
<ul>
<li v-for="(item, index) in list" :key="index">
<div @click="handleClick(item)">{{ item.name }}</div>
<template v-if="item.children">
<tree-menu :list="item.children"></tree-menu>
</template>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeMenu',
props: ['list'],
methods: {
handleClick(item) {
console.log(item.name)
}
}
}
</script>
三、右键新增删除编辑
对于一些需要进行增删改查操作的树形组件,我们可以为每一个节点绑定相关的右键菜单,通过弹出式菜单让用户可以方便地对节点进行修改。
<template>
<div>
<ul>
<li v-for="(item, index) in list" :key="index" @contextmenu.prevent="showContextMenu($event, item)">
<span @dblclick="handleEdit(item)">{{ item.name }}</span>
<template v-if="item.children">
<tree-node :list="item.children"></tree-node>
</template>
</li>
</ul>
<ul v-show="contextMenu.show" :style="{ left: contextMenu.left + 'px', top: contextMenu.top + 'px' }">
<li @click="handleAdd">新增节点</li>
<li @click="handleDelete">删除节点</li>
<li @click="handleEdit(contextMenu.node)">编辑节点</li>
</ul>
</div>
</template>
<script>
export default {
name: 'TreeNode',
props: ['list', 'level'],
data() {
return {
contextMenu: {
show: false,
node: null,
left: 0,
top: 0
}
}
},
methods: {
showContextMenu(event, item) {
event.stopPropagation()
event.preventDefault()
this.contextMenu.show = true
this.contextMenu.node = item
this.contextMenu.left = event.clientX
this.contextMenu.top = event.clientY
},
handleAdd() {
// 新增节点操作
},
handleDelete() {
// 删除节点操作
},
handleEdit(item) {
// 编辑节点操作
}
}
}
</script>
四、添加和删除
对于一些需要进行动态添加和删除的树形组件,我们可以通过数据源的变化来动态响应视图的变化。
<template>
<div>
<button @click="add">> 新增 </button>
<ul>
<li v-for="(item, index) in list" :key="index">
<div>{{ item.name }}</div>
<button @click="remove(index)"> 删除 </button>
<template v-if="item.children">
<tree-node :list="item.children"></tree-node>
</template>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'TreeNode',
props: ['list', 'level'],
methods: {
add() {
this.list.push({
name: `节点${this.list.length + 1}`,
children: []
})
},
remove(index) {
this.list.splice(index, 1)
}
}
}
</script>
五、树形组件选取
一些业务场景需要通过树形组件来进行数据的选取,比如城市选择器、商品分类选择器等等。我们可以通过绑定单选、多选的事件来实现选取功能。
<template>
<div>
<ul>
<li v-for="(item, index) in list" :key="index">
<label :for="'checkbox-' + index">
<input :id="'checkbox-' + index" type="checkbox" :checked="item.checked" @change="handleCheck(item)">
{{ item.name }}
</label>
<template v-if="item.children">
<tree-node :list="item.children"></tree-node>
</template>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'TreeNode',
props: ['list'],
methods: {
handleCheck(item) {
if (item.children && item.children.length) {
this.$emit('checkAll', item)
} else {
this.$emit('check', item)
}
}
}
}
</script>
六、总结
Vue树形组件是一个非常常用的组件,需要根据具体业务场景选择使用相关的库或者依据业务需求自主开发。在开发过程中,我们要特别关注组件的性能和用户体验,优化渲染、增加交互等技巧都可以有效地提高用户的满意度和使用体验。