Vue3通过 directive 实现 el-dropdown下拉菜单项最小宽度等于内容宽度

1. 初始效果与最终效果

原始效果最终效果
通过 direc在这里插入图片描述

2. 分析

el-dropdown API 并不提供配置项让我们实现下拉菜单项最小宽度等于内容宽度,但我们能发现它提供了 popper-class 用于自定义浮层类名。
那么我们是否可以通过 popper-class 配置项来实现想要的功能呢?或者通过 <el-dropdown-menu style="min-width: 100px;"> 这种形式进行最小宽度的设置?

答案明显是可行的,但有个问题:这两种方式设置最小宽度是需要提前知道内容宽度的值,那么就得在编码的时候限定一个值,限制性太大了。


3. 解决思路:directives

既然我们知道了通过 popper-class 配置项是可以实现效果的,所以我们只需要解决内容宽度计算并且设置下拉框最小宽度即可。
查阅 Vue3 文档,发现 directive 这个 API 可以让我们自定义指令,使 el-dropdown 渲染的时候进行自定义计算,获取内容宽度的同时设置下拉框选项的最小宽度。


4. 代码实现

  1. 定义 siem-dropdown 指令
    注:这里是新建了一个 siemDropdown.js 文件进行指令定义,目录:siem/share/directives/siemDropdown

    function setDropdownMinWidth(el, binding, vNode) {
        const { props, uid } = vNode.ctx; // 获取下拉菜单实例的 uid 和 props
        const siemDropdownClass = `siem-dropdown-${uid}`;
        if (props.popperClass?.indexOf(siemDropdownClass) === -1) {
            props.popperClass += ` ${siemDropdownClass}`; // 添加自定义浮层类名 popper-class
        }
    
        if (el) {
            setTimeout(() => {
                const $dom = document.querySelectorAll(`.${siemDropdownClass}`)[0]; // 获取下拉菜单项浮层元素
                if (el?.offsetWidth) {
                    $dom.style.minWidth = el.offsetWidth + 'px'; // 设置最小宽度为下拉菜单内容宽度
                }
            }, 100);
        }
    }
    
    const siemDropdown = {
        mounted: setDropdownMinWidth,
        updated: setDropdownMinWidth,
    };
    
    export default siemDropdown;
    
    
  2. 全局绑定 siem-dropdown 指令

    import siemDropdown from 'siem/share/directives/siemDropdown';
    
    export default function bindAllConfigs(APP){
        APP.directive('siem-dropdown', siemDropdown); // 全局绑定 siem-dropdown 指令
    }
    
  3. el-dropdown 使用 siem-dropdown 指令

    <el-dropdown
         v-siem-dropdown 
         @command="handleBatchOperation"
         style="margin-left: 8px;"
     >
         <el-button>
             <span style="display: inline-flex; align-items: center;">
                 用于测试的更多操作很长很长
                 <el-icon>
                     <arrow-down />
                 </el-icon>
             </span>
         </el-button>
         <template #dropdown>
             <el-dropdown-menu>
                 <el-dropdown-item command="test1">
                     测试1
                 </el-dropdown-item>
                 <el-dropdown-item command="test2">
                     测试2222
                 </el-dropdown-item>
                 <el-dropdown-item command="test3">
                     测试3
                 </el-dropdown-item>
             </el-dropdown-menu>
         </template>
     </el-dropdown>
    

小结

通过实现这个效果,学会了如何使用 directive,感觉还是很有收获的。
愿各位也能从中有所收获吧~~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值