二级联动菜单

请选择

代码展示:

<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的值得那个标签添加上一个类,类会变蓝色;
最后要注意冒泡事件,所以要阻止冒泡