文章目录
- 1. 初始效果与最终效果
- 2. 分析
- 3. 解决思路:`directives`
- 4. 代码实现
- 小结
1. 初始效果与最终效果
原始效果 | 最终效果 |
---|---|
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. 代码实现
-
定义
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;
-
全局绑定
siem-dropdown
指令import siemDropdown from 'siem/share/directives/siemDropdown'; export default function bindAllConfigs(APP){ APP.directive('siem-dropdown', siemDropdown); // 全局绑定 siem-dropdown 指令 }
-
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
,感觉还是很有收获的。
愿各位也能从中有所收获吧~~