theydy / notebook

记录读书笔记 + 知识整理,vuepress 迁移中 https://theydy.github.io/notebook/
0 stars 0 forks source link

重写 el-dropdown 的 initEvent 函数,支持 el-dropdown 嵌套 hover 二级下拉框时一级下拉框不消失 #28

Open theydy opened 3 years ago

theydy commented 3 years ago

问题

之前写需求碰到需要在 el-dropdown 里嵌套写 el-dropdown 的情况,表现形式类似 el-submenu 嵌套 el-submenu 在下拉选项里有一项 hover 会在旁边展开二级下拉选项。

然后写了个例子发现,现成的 el-dropdown 虽然可以嵌套,但是鼠标 hover 到二级下拉选项时,一级下拉选项就收起来了, 于是有了下面的修改尝试。

主要原理是让嵌套的 drowdown 元素在触发 mouseentermouseleave 事件时也触发父 drowdown 元素的 showhide 方法。

在线演试

https://codesandbox.io/s/el-dropdown-nested-1hs28?file=/src/main.js

main.js


(function () {
    // 为了 el-dropdown 组件 hover 时支持嵌套,重写 el-dropdown 的 initEvent 函数
    // element-ui@2.11.0

    const components = Vue.options.components;
    const methods = components.ElDropdown.options.methods;
    const initEvent = methods.initEvent;
    methods.initEvent = function () {
        initEvent.call(this);
        // 对于嵌套的 el-dropdown 添加 mouseenter,mouseleave 回调
        try {
            let { trigger, show, hide } = this;
            if (trigger === 'hover') {
                const secondaryDropDown = [];
                let children = [...this.$children];
                while (children.length) {
                    const deepChildren = [];
                    children.map(child => {
                        child.$options.componentName === 'ElDropdown' && secondaryDropDown.push(child);
                        if (child.$children.length) {
                            deepChildren.push(...child.$children);
                        }
                    })

                    children = deepChildren.length ? deepChildren : [];
                }
                secondaryDropDown.map(secondary => {
                    secondary.dropdownElm.addEventListener('mouseenter', show);
                    secondary.dropdownElm.addEventListener('mouseleave', hide);
                })
            }
        } catch (error) {
            console.log('重写 el-dropdown initEvent 错误', error);
        }
    }

})();

.vue 文件

    <el-dropdown
        class="dropdown"
        placement="bottom-end"
        trigger="hover"
    >
        <span class="el-dropdown-link">更多</span>
        <el-dropdown-menu slot="dropdown">
            <el-dropdown
                class="dropdown"
                style="width:100%"
                placement="left"
                trigger="hover"
            >
                <li class="el-dropdown-menu__item">1</li>
                <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item >1-1</el-dropdown-item>
                    <el-dropdown-item >1-2</el-dropdown-item>
                </el-dropdown-menu>
            </el-dropdown>
            <el-dropdown-item>2</el-dropdown-item>
            <el-dropdown-item>3</el-dropdown-item>
        </el-dropdown-menu>
    </el-dropdown>