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 相关文章推荐
Prototype使用指南之dom.js
Jan 10 Javascript
jQuery 对象中的类数组操作
Apr 27 Javascript
JS小框架 fly javascript framework
Nov 26 Javascript
读jQuery之二(两种扩展)
Jun 11 Javascript
js数组操作常用方法
May 08 Javascript
jQuery中[attribute]选择器用法实例
Dec 31 Javascript
JS实现复制内容到剪贴板功能兼容所有浏览器(推荐)
Jun 17 Javascript
微信小程序 封装http请求实例详解
Jan 16 Javascript
JS中绑定事件顺序(事件冒泡与事件捕获区别)
Jan 24 Javascript
JS实现发送短信验证后按钮倒计时功能(防止刷新倒计时失效)
Jul 07 Javascript
vue和better-scroll实现列表左右联动效果详解
Apr 29 Javascript
vue elementUI 表单校验的实现代码(多层嵌套)
Nov 06 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
删除无限分类并同时删除它下面的所有子分类的方法
2010/08/08 PHP
php轻松实现中英文混排字符串截取
2014/05/28 PHP
destoon安全设置中需要设置可写权限的目录及文件
2014/06/21 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
PHP hex2bin()函数用法讲解
2019/02/25 PHP
EASYUI TREEGRID异步加载数据实现方法
2012/08/22 Javascript
jquery入门—编写一个导航条(可伸缩)
2013/01/07 Javascript
jquery中show()、hide()和toggle()用法实例
2015/01/15 Javascript
常用的JavaScript WEB操作方法分享
2015/02/28 Javascript
简单理解Vue条件渲染
2016/12/03 Javascript
JavaScript限定范围拖拽及自定义滚动条应用(3)
2017/05/17 Javascript
引入JavaScript时alert弹出框显示中文乱码问题
2017/09/16 Javascript
详解vue axios用post提交的数据格式
2018/08/07 Javascript
详解webpack自定义loader初探
2018/08/29 Javascript
详解Webstorm 下的Angular2.0开发之路(图文)
2018/12/06 Javascript
微信小程序实现发送模板消息功能示例【通过openid推送消息给用户】
2019/05/05 Javascript
详解VSCode配置启动Vue项目
2019/05/14 Javascript
小程序和web画三角形实现解析
2019/09/02 Javascript
vue 实现input表单元素的disabled示例
2019/10/28 Javascript
彻底理解Python list切片原理
2017/10/27 Python
Python面向对象程序设计示例小结
2019/01/30 Python
对python For 循环的三种遍历方式解析
2019/02/01 Python
Python3获取拉勾网招聘信息的方法实例
2019/04/03 Python
Django-Model数据库操作(增删改查、连表结构)详解
2019/07/17 Python
解决Python命令行下退格,删除,方向键乱码(亲测有效)
2020/01/16 Python
python 获取当前目录下的文件目录和文件名实例代码详解
2020/03/10 Python
HTML5学习笔记之History API
2015/02/26 HTML / CSS
实例讲解利用HTML5 Canvas API操作图形旋转的方法
2016/03/22 HTML / CSS
上海某公司.net方向笔试题
2014/09/14 面试题
linux面试相关问题
2013/04/28 面试题
公司财务自我评价分享
2013/12/17 职场文书
2014年预备党员端正入党动机思想汇报
2014/09/13 职场文书
关于成绩下滑的自我检讨书
2014/09/20 职场文书
学校会议通知范文
2015/04/15 职场文书
导游词之杭州岳王庙
2019/11/13 职场文书
《勇者辞职不干了》上卷BD发售宣传CM公开
2022/04/08 日漫