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


Posted in Javascript onApril 10, 2018

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

Javascript 相关文章推荐
jQuery 遍历- 关于closest() 的方法介绍以及与parents()的方法区别分析
Apr 26 Javascript
JS实现可拖曳、可关闭的弹窗效果
Sep 26 Javascript
javascript设置和获取cookie的方法实例详解
Jan 05 Javascript
Vue组件BootPage实现简单的分页功能
Sep 12 Javascript
纯JS代码实现隔行变色鼠标移入高亮
Nov 23 Javascript
JavaScript组成、引入、输出、运算符基础知识讲解
Dec 08 Javascript
前端框架学习总结之Angular、React与Vue的比较详解
Mar 14 Javascript
JS实现汉字与Unicode码相互转换的方法详解
Apr 28 Javascript
angularjs通过过滤器返回超链接的方法
Oct 26 Javascript
如何在JavaScript中创建具有多个空格的字符串?
Feb 23 Javascript
详解阿里Node.js技术文档之process模块学习指南
Jan 04 Javascript
原生JS实现分页
Apr 19 Javascript
React如何避免重渲染
Apr 10 #Javascript
vue select组件的使用与禁用实现代码
Apr 10 #Javascript
vue 自定义 select内置组件
Apr 10 #Javascript
JavaScript如何对图片进行黑白化
Apr 10 #Javascript
axios 处理 302 状态码的解决方法
Apr 10 #Javascript
vue.js中npm安装教程图解
Apr 10 #Javascript
vue实现验证码按钮倒计时功能
Apr 10 #Javascript
You might like
php 解决旧系统 查出所有数据分页的类
2012/08/27 PHP
PHP中数组定义的几种方法
2013/09/01 PHP
PHP中time(),date(),mktime()区别介绍
2013/09/28 PHP
php设置允许大文件上传示例代码
2014/03/10 PHP
Linux系统中为php添加pcntl扩展
2016/08/28 PHP
yii2.0整合阿里云oss的示例代码
2017/09/19 PHP
jquery获取元素值的方法(常见的表单元素)
2013/11/15 Javascript
JavaScript自定义日期格式化函数详细解析
2014/01/14 Javascript
JS解析XML实例分析
2015/01/30 Javascript
jquery实现多屏多图焦点图切换特效的方法
2015/05/04 Javascript
jQuery添加options点击事件并传值实例代码
2016/05/18 Javascript
vue组件父子间通信之综合练习(聊天室)
2017/11/07 Javascript
js中DOM事件绑定分析
2018/03/18 Javascript
Angular5中调用第三方库及jQuery的添加的方法
2018/06/07 jQuery
JavaScript引用类型Function实例详解
2018/08/09 Javascript
基于vue中对鼠标划过事件的处理方式详解
2018/08/22 Javascript
jQuery+css last-child实现选择最后一个子元素操作示例
2018/12/10 jQuery
详解关于element级联选择器数据回显问题
2019/02/20 Javascript
Vue.js轮播图走马灯代码实例(全)
2019/05/08 Javascript
Vue CLI2升级至Vue CLI3的方法步骤
2019/05/20 Javascript
让python同时兼容python2和python3的8个技巧分享
2014/07/11 Python
Python中方法链的使用方法
2016/02/23 Python
Python使用Matplotlib实现雨点图动画效果的方法
2017/12/23 Python
TensorFlow实现AutoEncoder自编码器
2018/03/09 Python
用Python从0开始实现一个中文拼音输入法的思路详解
2019/07/20 Python
200行python代码实现贪吃蛇游戏
2020/04/24 Python
深入浅析HTML5中的article和section的区别
2018/05/15 HTML / CSS
意大利团购网站:Groupon意大利
2016/10/11 全球购物
.net软件工程师面试题
2015/03/31 面试题
2019年分享net面试的经历和题目
2016/08/07 面试题
八一建军节感言
2014/02/28 职场文书
环境建设实施方案
2014/03/14 职场文书
法定代表人授权委托书范文
2014/08/02 职场文书
党员干部观看《周恩来四个昼夜》思想汇报
2014/09/10 职场文书
幼儿园庆六一主持词
2015/06/30 职场文书
go使用Gin框架利用阿里云实现短信验证码功能
2021/08/04 Golang