Vue Element-UI Cascader 级联选择器中子菜单的显示与隐藏

最近有发现一个在Elment-UI低版本中级联组件出现的BUG(楼主的版本是2.4.11),先上图来直观的感受下:

Vue Element-UI Cascader 级联选择器中子菜单的显示与隐藏_第1张图片
即:若展开过含有子菜单的菜单,当鼠标再移入到没有子菜单的菜单上时,仍然会显示上一次展开过的菜单的子菜单。

在一般的思维逻辑中这显然是一个BUG,移入没有子菜单的菜单时应该不再展开任何子菜单才对,那么应该如何解决这个问题呢?于是我开始查找相关的资料,也确实发现了几篇文章,其中有一篇文章中的作法引起了我的注意,并将其做法应用到自身的代码中来,结果却差强人意。

先贴一下原帖链接:vue element el-Cascader 级联选择器 收起二级菜单的问题解决办法详解_@必意玲-程序员宅基地

其次就是应用中出现的问题,如果有耐心的话可以看完下面的演示:

有了上述问题的存在,那就无法投入到实际应用当中。讨论之余,最后也是在同事大佬的帮助下,就上述的方法中作出一点改良,才终于是解决了这个问题。
重点在于 popper-class 以及 鼠标事件的挂载,以下是代码详情:

HTML

<template>
    <div class="block">
        <span class="demonstration">hover 触发子菜单</span>
        <el-cascader
                popper-class="cascaderRadio"
                v-model="value"
                :options="options"
                :props="{ expandTrigger: 'hover' }"
                @change="handleChange">
            <template slot-scope="{ node, data}">
                <span class="custom-node leaf" v-if="node.isLeaf == 0" @mouseenter="mouseenterLeaf(node)">{{node.label}}</span>
                <span v-else class="custom-node noLeaf" @mouseenter="mouseenterSubcat(node)">{{node.label}}</span>
            </template>
        </el-cascader>
    </div>
</template>

JavaScript

<script>
    export default {
        data() {
            return {
                value: [],
                options: [{
                    value: 'zhinan',
                    label: '指南',
                    children: [{
                        value: 'shejiyuanze',
                        label: '设计原则',
                        children: [{
                            value: 'yizhi',
                            label: '一致'
                        }, {
                            value: 'fankui',
                            label: '反馈'
                        }, {
                            value: 'xiaolv',
                            label: '效率'
                        }, {
                            value: 'kekong',
                            label: '可控'
                        }]
                    }, {
                        value: 'daohang',
                        label: '导航',
                        children: [{
                            value: 'cexiangdaohang',
                            label: '侧向导航'
                        }, {
                            value: 'dingbudaohang',
                            label: '顶部导航'
                        }]
                    }]
                }, {
                    value: 'zujian',
                    label: '组件',
                }, {
                    value: 'ziyuan',
                    label: '资源',
                    children: [{
                        value: 'axure',
                        label: 'Axure Components'
                    }, {
                        value: 'sketch',
                        label: 'Sketch Templates'
                    }, {
                        value: 'jiaohu',
                        label: '组件交互文档'
                    }]
                }]
            };
        },
        methods: {
            handleChange(value) {
                console.log(value);
            },
            //联级选择鼠标移入
            mouseenterSubcat (node) {
                // console.log('联级选择鼠标移入');
                let el_node = document.querySelectorAll('.el-popper.el-cascader__dropdown.specialCascaderRadio .el-cascader-panel .el-cascader-menu');
                if (el_node[node.level] && el_node.length > 0) {
                    el_node[node.level].style.display = "none";
                    this.cascaderRecursion(el_node,node)
                } else {
                    console.log('none');
                }
            },
            //联级选择鼠标移出
            mouseenterLeaf (node) {
                // console.log('联级选择鼠标移出');
                let el_node = document.querySelectorAll('.el-popper.el-cascader__dropdown.specialCascaderRadio .el-cascader-panel .el-cascader-menu');
                if (el_node[node.level] && el_node.length > 0) {
                    el_node[node.level].style.display = "block";
                }
            },
            // 级联的递归(因为层级数量未知)
            cascaderRecursion(el_node,node){
                function handle(i){
                    if(el_node[node.level + i]){
                        el_node[node.level + i].style.display = "none";
                        i++
                        handle(i)
                    }else{
                        return
                    }
                }
                handle(1)
            },
        }
    };
</script>

CSS

<style>
    .cascaderRadio li {
        padding: 0px;
    }
    .cascaderRadio .el-cascader-node__label{
        padding: 0px;
    }
    .custom-node {
        padding: 6px 20px;
        display: block;
        height: 34px;
        line-height: 34px;
    }
</style>

最后展示一下成果

Vue Element-UI Cascader 级联选择器中子菜单的显示与隐藏_第2张图片

你可能感兴趣的:(vue.js,前端,elementui)