600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 手写Vue个人组件库——fl-Tree 树形选择器

手写Vue个人组件库——fl-Tree 树形选择器

时间:2021-10-18 03:16:21

相关推荐

手写Vue个人组件库——fl-Tree 树形选择器

Tree 树形控件

用清晰的层级结构展示信息,可展开或折叠。

基础用法

基础的树形结构展示。

通过dataSource绑定数据源,使用afterToggle获得每次展开收起的回调方法。

同时你还可以配置数据源中的display决定默认展开的选项。

<template><fl-Tree :dateSource = "treeData" @afterToggle = "afterToggle"></fl-Tree></template><script>export default{data() {return {data: [{label: '一级 1',display:false,children: [{label: '二级 1-1',display:false,children: [{label: '三级 1-1-1',display:false,}]}]}, {label: '一级 2',display:false,children: [{label: '二级 2-1',display:false,children: [{label: '三级 2-1-1',display:false,}]}, {label: '二级 2-2',display:false,children: [{label: '三级 2-2-1',display:false,}]}]}, {label: '一级 3',display:false,children: [{label: '二级 3-1',display:false,children: [{label: '三级 3-1-1',display:false,}]}, {label: '二级 3-2',display:false,children: [{label: '三级 3-2-1',display:false,}]}]}],}}}</script>

可选择

适用于需要选择层级时使用。

为了更好的使用选择树形选择器,你需要配置avaCheckeddefaultOpen属性。

你可以通过checked决定每次渲染时默认选中的选项。

<template><fl-Tree :dateSource = "treeData" @afterToggle = "afterToggle" @handleChecked = "handleChecked" avaChecked defaultOpen></fl-Tree></template><script>export default{data() {return {data: [{label: '一级 1',checked: false,children: [{label: '二级 1-1',checked: false,children: [{label: '三级 1-1-1',checked: false,}]}]}, {label: '一级 2',checked: false,children: [{label: '二级 2-1',checked: false,children: [{label: '三级 2-1-1',checked: false,}]}, {label: '二级 2-2',checked: false,children: [{label: '三级 2-2-1',checked: false,}]}]}, {label: '一级 3',checked: false,children: [{label: '二级 3-1',checked: false,children: [{label: '三级 3-1-1',checked: false,}]}, {label: '二级 3-2',checked: false,children: [{label: '三级 3-2-1',checked: false,}]}]}],}}}</script>

禁用状态

可将 Tree 的某些节点设置为禁用状态。

通过对dataSource中的选项进行disabled属性的配置。

真正意义上的数组对象元素控制视图变化。

<template><fl-Tree :dateSource = "treeData" @afterToggle = "afterToggle" @handleChecked = "handleChecked" avaChecked defaultOpen></fl-Tree></template><script>export default{data() {return {data: [{label: '一级 1',checked: false,children: [{label: '二级 1-1',checked: false,children: [{label: '三级 1-1-1',checked: false,disabled: true,}]}]}, {label: '一级 2',checked: false,disabled: true,children: [{label: '二级 2-1',checked: false,children: [{label: '三级 2-1-1',checked: false,}]}, {label: '二级 2-2',checked: false,children: [{label: '三级 2-2-1',checked: false,}]}]}, {label: '一级 3',checked: false,children: [{label: '二级 3-1',checked: false,disabled: true,children: [{label: '三级 3-1-1',checked: false,}]}, {label: '二级 3-2',checked: false,children: [{label: '三级 3-2-1',checked: false,}]}]}],}}}</script>

手风琴模式

对于同一级的节点,每次只能展开一个。

配置onlyShowOne属性即可。

<template><fl-Tree :dateSource = "treeData" @afterToggle = "afterToggle" @handleChecked = "handleChecked" avaChecked defaultOpen showOnlyOne></fl-Tree></template><script>export default{data() {return {data: [{label: '一级 1',checked: false,children: [{label: '二级 1-1',checked: false,children: [{label: '三级 1-1-1',checked: false,disabled: true,}]}]}, {label: '一级 2',checked: false,disabled: true,children: [{label: '二级 2-1',checked: false,children: [{label: '三级 2-1-1',checked: false,}]}, {label: '二级 2-2',checked: false,children: [{label: '三级 2-2-1',checked: false,}]}]}, {label: '一级 3',checked: false,children: [{label: '二级 3-1',checked: false,disabled: true,children: [{label: '三级 3-1-1',checked: false,}]}, {label: '二级 3-2',checked: false,children: [{label: '三级 3-2-1',checked: false,}]}]}],}}}</script>

在点击和收缩展开时做些什么

你可以通过@afterToggle@handleChecked这两个内置事情,监听点击和收缩展开时的回调函数。

返回的将是正在被操作的节点。

<fl-Tree:dateSource = "treeData"avaCheckeddefaultOpenonlyShowOne@afterToggle = "afterToggle"@handleChecked = "handleChecked"></fl-Tree>

Attributes

源码:

<template><div class = "tree"><div class = "firstTree" v-for = "item in dateSource" :key = "item.label"><div><i :class = "item.display ? 'el-icon-caret-bottom' : 'el-icon-caret-right'" @click = "showFirstChild(item)"></i><input type = "checkbox" @change = "checkTree(item,1)" :checked = "item.checked" v-if = "$attrs.avaChecked == ''" :disabled = "item.disabled ? true : false"><span>{{item.label}}</span></div><div class = "secordTree" v-for = "item2 in item.children" :key = "item2.label"><div v-if = "item.display"><i :class = "item2.display ? 'el-icon-caret-bottom' : 'el-icon-caret-right'" @click = "showSecordChild(item,item2)"></i><input type = "checkbox" @change = "checkTree([item,item2],2)" :checked = "item2.checked" v-if = "$attrs.avaChecked == ''" :disabled = "item2.disabled || item.disabled ? true : false"><span>{{item2.label}}</span></div><div class = "thirdree" v-for = "item3 in item2.children" :key = "item3.label"><div v-if = "item2.display"><input type = "checkbox" @change = "checkTree([item,item2,item3],3)" :checked = "item3.checked" v-if = "$attrs.avaChecked == ''" :disabled = "item3.disabled || item2.disabled || item.disabled ? true : false"><!-- <i class = "el-icon-caret-right"></i> --><span>{{item3.label}}</span></div></div></div></div></div></template><script>export default {props: {dateSource: {type: Array,default: []},},data(){return {}},methods: {//切换一级列表showFirstChild(item){var index = this.dateSource.findIndex(data=>{return data == item})if(this.dateSource[index].display){this.dateSource[index].children.map(item=>{return item.display = false})}if(this.$attrs.onlyShowOne == ''){this.dateSource.map(item=>{item.children.map(item2=>{item2.children.map(item3=>{return item3.display = false;})return item2.display = false;})return item.display = false})}this.dateSource[index].display = !this.dateSource[index].displaythis.$emit('afterToggle',this.dateSource[index])},//切换二级列表showSecordChild(item,item2) {//一级下标var index = this.dateSource.findIndex(data=>{return data == item})//二级下标var index2 = item.children.findIndex(data=>{return data == item2})this.dateSource[index].children[index2].display = !this.dateSource[index].children[index2].displaythis.$emit('afterToggle',this.dateSource[index].children[index2])},checkTree(data,level){var index;//一级分类选中if(level == 1){index = this.dateSource.findIndex(item=>{return item == data})this.dateSource[index].checked = !this.dateSource[index].checked;this.dateSource[index].children.map(item=>{if(this.dateSource[index].checked){if(!item.disabled){item.children.map(item2=>{if(!item2.disabled){return item2.checked = true}})return item.checked = true}}else{item.children.map(item2=>{return item2.checked = false})return item.checked = false}})this.$emit('handleChecked',this.dateSource[index])}//二级分类选中if(level == 2){var firstIndex = this.dateSource.findIndex(item=>{return item == data[0]})index = this.dateSource[firstIndex].children.findIndex(item=>{return item == data[1]})this.dateSource[firstIndex].children[index].checked = !this.dateSource[firstIndex].children[index].checkedif(!this.dateSource[firstIndex].children[index].checked){this.dateSource[firstIndex].checked = false;}this.dateSource[firstIndex].children[index].children.map(item=>{if(this.dateSource[firstIndex].children[index].checked){if(!item.disabled){return item.checked = true}}return item.checked = false})//第二节被选中后需更新第一节选中状态this.dateSource[firstIndex].checked = this.checkedChildAll(this.dateSource[firstIndex].children)this.$emit('handleChecked',this.dateSource[firstIndex].children[index])}//三级分类选中if(level == 3){var firstIndex = this.dateSource.findIndex(item=>{return item == data[0]})var secordIndex = this.dateSource[firstIndex].children.findIndex(item=>{return item == data[1]})index = this.dateSource[firstIndex].children[secordIndex].children.findIndex(item=>{return item == data[2]})this.dateSource[firstIndex].children[secordIndex].children[index].checked = !this.dateSource[firstIndex].children[secordIndex].children[index].checked//第三节被选中后需更新第二节、第一节的选中状态this.dateSource[firstIndex].children[secordIndex].checked = this.checkedChildAll(this.dateSource[firstIndex].children[secordIndex].children)this.dateSource[firstIndex].checked = this.checkedChildAll(this.dateSource[firstIndex].children)this.$emit('handleChecked',this.dateSource[firstIndex].children[secordIndex].children[index])}},checkedChildAll(arr){//判断该数组的子节点是否全被选中return arr.every(item=>{return item.checked})}},}</script><style scoped>.tree{/* width:200px; */}.secordTree{padding-left:20px;}.thirdree{padding-left:40px;}i{cursor: pointer;}</style>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。