vue单个组件实现无限层级多选菜单功能
程序员文章站
2023-11-11 21:36:40
wtree.vue
原理:每一个多选框都是一个节点,每个节点就是一个wtree组件,有父级(*level为0),有子级(底层list[]是空的),组件之间状...
wtree.vue
原理:每一个多选框都是一个节点,每个节点就是一个wtree组件,有父级(*level为0),有子级(底层list[]是空的),组件之间状态传递是通过组件通信传递,对于外部数据checklist数组的修改是通过store实现的。初始化从底层状态传递到上层,一层一层传递。改变状态,不同状态改变,修改checklist数组。大概就这个思路,下面是代码:
<template> <div> <div > <span v-for="o in levelnum"> </span> <i v-if="item.list" :class="open ? openclass : closeclass" @click="showsub" style="color: #00d6b2"></i> <span v-else> </span> <span> <a @click="changestate"> <img src="./../assets/selectedall.png" v-if="selectedstate === 'all'" width="15px" height="15px"/> <img src="./../assets/selectedsub.png" v-if="selectedstate === 'sub'" width="15px" height="15px"/> <img src="./../assets/selectednull.png" v-if="selectedstate === 'null'" width="15px" height="15px"/> </a> </span> <span>{{item.name}}</span> </div> <component v-show="open" :is="node" :item="o" :state="statesub" v-for="o of item.list" :key="o.key" :level="levelnum" v-on:changetopar="changebysub"> </component> </div> </template> <script> export default { name: 'wtree', props: ['item', 'level', 'state'], data () { return { open: true, node: 'wtree', // 控制菜单开关的 selected: false, // 选中的情况下 selectedstate: 'null', // 子组件被选中的情况下向上传递all/sub/null origininfo: 'create', // 组件信息源,create/parent/children/this openclass: 'el-icon-caret-bottom', closeclass: 'el-icon-caret-right', selectclass: 'el-icon-check', selectbg: '#1c8de0', list: [], createswitch: true } }, computed: { levelnum () { return (this.level + 1) }, statesub () { return { selected: this.selected, origininfo: this.origininfo } } }, methods: { showsub () { this.open = !this.open }, changestate () { if (this.selected) { this.selected = false this.selectedstate = 'null' this.origininfo = 'this' for (let o of this.list) { o.selectedstate = 'null' } } else { this.selected = true this.selectedstate = 'all' this.origininfo = 'this' for (let o of this.list) { o.selectedstate = 'all' } } let data = { id: this.item.menuid, selectedstate: this.selectedstate, origininfo: 'parent' } this.$emit('changetopar', data) }, changebysub (data) { // 如果是父组件true,判断状态,未被选中,添加id到list,selectsub=true,通知父组件,添加store的数组中,选中通知父组件,this.list.length=this.length状态改为selected // 修改自身状态,添加list let temp = data if (data.origininfo === 'create') { this.list.push(data) } else { this.origininfo = 'parent' let statenull = 'null' let stateall = 'all' let statesub = 'sub' for (let o of this.list) { if (o.id === temp.id) { o.selectedstate = temp.selectedstate } if (o.selectedstate !== 'all') { stateall = null } if (o.selectedstate !== 'null') { statenull = null } } if (statenull) { this.selectedstate = statenull this.selected = false } else if (stateall) { this.selectedstate = stateall this.selected = true } else { this.selectedstate = statesub this.selected = true } let data = { id: this.item.menuid, selectedstate: this.selectedstate, origininfo: 'parent' } this.$emit('changetopar', data) } } }, watch: { selected () { // 初始化 if (this.origininfo === 'create') { // 不改变值 } else { // 改变值******** if (this.selected) { // 添加值 this.$store.commit('push_check_list', this.item.menuid) } else { // 删除值 this.$store.commit('splice_check_list', this.item.menuid) } } }, state () { // 子组件得到通知,如果状态一直,不去改变,如果状态不一致改变 if (this.state.origininfo === 'this') { this.origininfo = 'this' } if (this.origininfo === 'create') { this.origininfo = 'children' } else { if (this.state.origininfo !== 'parent') { if (this.state.selected) { this.selected = true this.selectedstate = 'all' if (this.list !== []) { for (let o of this.list) { o.selectedstate = 'all' } } } else { this.selected = false this.selectedstate = 'null' if (this.list !== []) { for (let o of this.list) { o.selectedstate = 'null' } } } } } }, list () { // 初始化数组 if (this.list.length === this.item.list.length) { let statenull = 'null' let stateall = 'all' let statesub = 'sub' for (let o of this.list) { if (o.selectedstate !== 'all') { stateall = null } if (o.selectedstate !== 'null') { statenull = null } } if (statenull) { this.selectedstate = statenull this.selected = false } else if (stateall) { this.selectedstate = stateall this.selected = true } else { this.selectedstate = statesub this.selected = true } let data = { id: this.item.menuid, selectedstate: this.selectedstate, origininfo: 'create' } this.$emit('changetopar', data) } } }, created () { // 初始化,把每个组件,从最底层添加到节点列表中,这样每个子组件都在list中了,就是origininfo=create的情况下添加数组,就不用判断数组长度,直接改变状态 if (this.createswitch) { let i = this.$store.state.checklist.indexof(this.item.menuid) console.log(!this.item.list) console.log('-----------------------初始化') if (!this.item.list) { if (i > -1) { this.selectedstate = 'all' this.selected = true } else { this.selectedstate = 'null' this.selected = false } let data = { id: this.item.menuid, selectedstate: this.selectedstate, origininfo: 'create' } this.$emit('changetopar', data) this.origininfo = 'this' } this.createswitch = false } console.log(this.state) console.log('----------------created') }, updated () { console.log('-------updated=======') let i = this.$store.state.checklist.indexof(this.item.menuid) console.log(!this.item.list) console.log('-----------------------初始化') if (!this.item.list) { if (i > -1) { this.selectedstate = 'all' this.selected = true } else { this.selectedstate = 'null' this.selected = false } let data = { id: this.item.menuid, selectedstate: this.selectedstate, origininfo: 'parent' } this.$emit('changetopar', data) this.origininfo = 'this' } }, mounted () { console.log('=========mounted-----') } } </script>
调用 orglist带有层级的json数组
<w-tree v-for="o of orglist" :item="o" :level="0" :key="o.key"></w-tree>
总结
以上所述是小编给大家介绍vue单个组件实现无限层级多选菜单,希望对大家有所帮助
上一篇: 软文营销文案如何创作才能更有“生命力”
下一篇: 产品销量上不去?软文营销帮你忙