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 相关文章推荐
js实现ASP分页函数 HTML分页函数
Sep 22 Javascript
JavaScript Event学习第八章 事件的顺序
Feb 07 Javascript
javascript 在firebug调试时用console.log的方法
May 10 Javascript
以WordPress为例讲解jQuery美化页面Title的方法
May 23 Javascript
jQuery Easyui DataGrid点击某个单元格即进入编辑状态焦点移开后保存数据
Aug 15 Javascript
jQuery制作图片旋转效果
Feb 02 Javascript
Vue2.0用 watch 观察 prop 变化(不触发)
Sep 08 Javascript
JavaScript简单实现关键字文本搜索高亮显示功能示例
Jul 25 Javascript
jQuery操作cookie的示例代码
Jun 05 jQuery
小程序自定义导航栏兼容适配所有机型(附完整案例)
Apr 26 Javascript
JSONP解决JS跨域问题的实现
May 25 Javascript
VUE中V-IF条件判断改变元素的样式操作
Aug 09 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
使用array mutisort 实现按某字段对数据排序
2013/06/18 PHP
php5.3 不支持 session_register() 此函数已启用的解决方法
2013/11/12 PHP
微信支付开发教程(一)微信支付URL配置
2014/05/28 PHP
Laravel框架表单验证详解
2014/09/04 PHP
php 实现银联商务H5支付的示例代码
2019/10/12 PHP
PHP快速导出百万级数据到CSV或者EXCEL文件
2020/11/27 PHP
使用javascript实现页面定时跳转总结篇
2013/09/21 Javascript
文本框只能选择数据到文本框禁止手动输入
2013/11/22 Javascript
在JavaScript中使用timer示例
2014/05/08 Javascript
Js+Jq获取URL参数的集中方法示例代码
2014/05/20 Javascript
JQuery 在线引用及测试引用是否成功
2014/06/24 Javascript
影响jQuery使用的14个方面
2014/09/01 Javascript
js动态添加的DIV中的onclick事件简单实例
2016/07/25 Javascript
AngularJS实现一次监听多个值发生的变化
2016/08/31 Javascript
Vue父子模版传值及组件传值的三种方法
2017/11/27 Javascript
微信小程序模板template简单用法示例
2018/12/04 Javascript
15分钟上手vue3.0(小结)
2020/05/20 Javascript
python网络编程学习笔记(二):socket建立网络客户端
2014/06/09 Python
python修改list中所有元素类型的三种方法
2018/04/09 Python
pycharm配置pyqt5-tools开发环境的方法步骤
2019/02/11 Python
利用PyCharm操作Github(仓库新建、更新,代码回滚)
2019/12/18 Python
Pytorch 多块GPU的使用详解
2019/12/31 Python
Pytorch evaluation每次运行结果不同的解决
2020/01/02 Python
python处理RSTP视频流过程解析
2020/01/11 Python
python实现简单坦克大战
2020/03/27 Python
浅谈Html5多线程开发之WebWorkers
2018/05/02 HTML / CSS
Coach澳大利亚官方网站:美国著名时尚奢侈品牌
2017/05/24 全球购物
Kneipp克奈圃美国官网:德国百年精油配方的传承
2018/02/07 全球购物
StringBuilder和String的区别
2015/05/18 面试题
法学函授自我鉴定
2014/02/06 职场文书
个人自荐材料
2014/05/23 职场文书
党员学习党的群众路线思想汇报(5篇)
2014/09/10 职场文书
学校党的群众路线教育实践活动制度建设计划
2014/11/03 职场文书
2015年校长新年寄语
2014/12/08 职场文书
早会开场白台词大全
2015/06/01 职场文书
深入理解CSS 中 transform matrix矩阵变换问题
2021/08/30 HTML / CSS