欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

vue单个组件实现无限层级多选菜单功能

程序员文章站 2022-06-14 11:34:30
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单个组件实现无限层级多选菜单,希望对大家有所帮助