使用Vue2封装Tree组件
一、介绍
Tree组件实现,原理就是递归,数据是递归的,所以组件也是递归,将数据一层一层的渲染,简易结构如下
<template>
<div class="main">
<div v-if="data" v-for="(item, index) in data">
<input type="checkbox" ref="parent" @click="updateDisplay($event, index)" :id="item.id"><label :for="item.id">
{
{ item.label }}</label>
</div>
<Tree v-if="item.children" ref="child" :data-index="index" :data="item.children" class="child" />
</div>
</div>
</template>
<script>
export default {
name: 'Tree',
props: {
data: {
type: Array
}
}
}
</script>
<style scoped lang='less'>
@import url('./reset.css');
</style>
-
组件接收一个父组件的data,将自己作为子组件传入 item.children
-
当点击input (checkbox)时,要获取当前input 使得点击他时他所有的子节点都要被选中所有要给子组件Tree添加ref=“child”,或者被取消,父节点要根据子节点的被选中数量来判断是否为选中,还是半选中状态给 input添加ref=“parent”。
-
由于渲染是一层一层渲染 ,第一次渲染时会获取父组件input时最外层的所有input,所以需要给子组件添加自定义属性:data-index=“index”利用父组件的索引,找到自己真正的父节点
例如:如果最外层有两个数据 那么就会递归渲染出2次 input 和一个2个Tree子组件
<template> <div class="main"> <div v-if="data" v-for="(item, index) in data"> <input type="checkbox" ref="parent" @click="updateDisplay($event, index)" :id="item.id"><label :for="item.id"> { { item.label }}</label> </div> <Tree v-if="item.children" ref="child" :data-index="index" :data="item.children" class="child" /> </div> </div> <template> <div class="main"> <div v-if="data" v-for="(item, index) in data"> <input type="checkbox" ref="parent" @click="updateDisplay($event, index)" :id="item.id"><label :for="item.id"> { { item.label }}</label> </div> <Tree v-if="item.children" ref="child" :data-index="index" :data="item.children" class="child" /> </div> </div> </template> </template> <script> export default { name: 'Tree', props: { data: { type: Array } } } </script> <style scoped lang='less'> @import url('./reset.css'); </style>
二、组件代码
1.改变input复选框的样式,Tree/reset.css
input[type="checkbox"]:checked {
box-shadow: 0 0 0 3px hotpink;
border:hotpink ;
}
:root {
--dark: #24d3d3;
}
/* input[type="checkbox"]{
display: none;
} */
label {
display: flex;
align-items: center;
grid-gap: 16px;
cursor: pointer;
}
label .checkbox {