怎么在vue中实现无限层级多选菜单功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
<template>
<div>
<div >
<span v-for="o in levelNum"> </span>
<i v-if="item.list" :class="open ? openClass : closeClass" @click="showSub" ></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具体轻量级框架、简单易学、双向数据绑定、组件化、数据和结构的分离、虚拟DOM、运行速度快等优势,Vue中页面使用的是局部刷新,不用每次跳转页面都要请求所有数据和dom,可以大大提升访问速度和用户体验。
关于怎么在vue中实现无限层级多选菜单功能问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。