二级联动菜单
请选择
代码展示:
<template>
<div id="app" :class="{'on':isVisibleFirst}">
<div class="select-box" @click="showFirstLayer">
<div class="curr" :class="{'on':isVisibleFirst}">
<span v-if="selectionBoxDisplay">请选择</span>
<span v-else>{{theString}}</span>
<span class="arrow"></span>
</div>
<div class="list-box clearfix" v-if="isVisibleFirst">
<div class="list">
<div class="item" v-for="(theitem,index) in list" @click="givenValueOfCurr(index)" :class="{'active':index==curr}">{{theitem.name}}</div>
</div>
<div class="list" v-if="isVisibleSecond">
<div class="item" v-for="(theSeItem,index1) in list[curr].children" @click="clickingSecondLayer(index1)" :class="{'active':index1==currSec}">{{theSeItem.name}}</div>
</div>
<div class="icon"></div>
</div>
</div>
</div>
</template>
逻辑代码:
data(){
return{
list: [
{
name: '陕西省',
children: [{
name: '西安市'
}, {
name: '铜川市'
}]
},
{
name: '山东省',
children: [
{
name: '德州市'
},
{
name: '日照市'
},
{
name: '泰安市'
}]
},
{
name: '山西省',
children: [
{
name: '吕梁市'
},
{
name: '临汾市'
},
{
name: '太原市'
}
]
}],
curr : -1,
currSec: -1,
firstTimeClick:0,
isVisibleFirst:false,
isVisibleSecond:false,
theString:"",
selectionBoxDisplay:true,
}
},
methods: {
showFirstLayer() {
this.isVisibleFirst = true;
this.firstTimeClick += 1;
if (this.firstTimeClick > 1) {
this.isVisibleSecond = true;
}
this.selectionBoxDisplay = false;
},
givenValueOfCurr(index) {
this.curr = index;
// console.log(this.list[this.curr].children);
this.isVisibleSecond = true;
this.currSec = -1;
this.theString = this.list[this.curr].name + "\/";
},
clickingSecondLayer(index1) {
this.isVisibleFirst = false;
this.currSec = index1;
// console.log(this.isVisibleFirst);
this.isVisibleSecond = false;
event.stopPropagation();
this.theString += this.list[this.curr].children[this.currSec].name;
}
}
css样式:
* {
padding: 0;
margin: 0;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
a {
text-decoration: none;
}
.clearfix:before,
.clearfix:after {
content: ' ';
display: table;
}
.clearfix:after {
clear: both;
}
input {
outline: none;
}
ol,
ul {
list-style: none;
}
body {
padding: 20px;
}
.select-box {
position: relative;
}
.select-box .curr {
width: 240px;
padding-left: 15px;
padding-right: 30px;
border: 1px solid #ddd;
border-radius: 5px;
height: 40px;
line-height: 40px;
font-size: 14px;
position: relative;
z-index: 15;
background-color: white;
}
.select-box .curr:hover {
border-color: #aaa;
cursor: pointer;
}
#app{
margin-top: 20px;
margin-bottom: 222px;
}
.arrow {
position: absolute;
right: 10px;
top: 17px;
display: block;
width: 10px;
height: 10px;
border-left: 1px solid #aaa;
border-top: 1px solid #aaa;
transform: rotate(225deg);
transform-origin: 2px 2px;
transition: 200ms;
}
.on .arrow {
transform: rotate(45deg);
}
.list-box {
position: absolute;
top: 30px;
left: 0;
border: 1px solid #ddd;
box-shadow: 0px 0px 8px 0px #ccc;
padding: 5px 0;
z-index: 10;
transition: 200ms;
}
.on .list-box {
top: 50px;
}
.list-box .list {
float: left;
width: 180px;
height: 204px;
overflow: auto;
border-left: 1px solid #ccc;
}
.list-box .list.first {
border: none;
}
.list .item {
height: 38px;
line-height: 38px;
padding-left: 15px;
font-size: 14px;
cursor: pointer;
position: relative;
}
.list .item:hover {
background-color: rgb(245, 247, 250);
}
.list .item.active {
color: #409EFF;
font-weight: bold;
}
.list .icon {
position: absolute;
top: -6px;
left: 30px;
width: 10px;
height: 10px;
border-left: 1px solid #ddd;
border-top: 1px solid #ddd;
z-index: 20;
transform: rotate(45deg);
background-color: white;
}
.list .arrow-icon {
position: absolute;
right: 10px;
top: 17px;
display: block;
width: 10px;
height: 10px;
border-left: 1px solid #aaa;
border-top: 1px solid #aaa;
transform: rotate(135deg);
transform-origin: 2px 2px;
transition: 200ms;
}
注意
主要的技术,一个是v-if会让点击后的一级菜单显示出来,然后v-if点击一级菜单中的某个元素后,在v-for里面用上一个下标,把下标传入,然后会相应的把数据放到二级菜单中;
选中变色的话是 v-bind:class的应用, :class的效果就是选中后让curr(也就是当前选中的值)对应的Index的值得那个标签添加上一个类,类会变蓝色;
最后要注意冒泡事件,所以要阻止冒泡