首页 > 编程 > JavaScript > 正文

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

2019-11-19 14:02:10
字体:
来源:转载
供稿:网友

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单个组件实现无限层级多选菜单,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表