踩坑记24 el-form label 对齐方式 | v-click-outside 组件外点击触发 | el-popover click激活 点击外部/取消隐藏 element-plus
2021.9.16
坑74(el-form、label、对齐方式):el-form 设置标签 label 的对齐方式 label-position 属性为 right 或 left 时,需同时设置标签宽度 label-width 属性。若无设置,标签 label 的宽度会随标签内容自动调整,无对齐效果( label 看似左对齐,但内容头部不会对齐,会贴着 label )。默认对齐方式为 right ,右对齐。可选值为 right、left、top ( label单独在内容上方一行 )。
参考: Form 表单 | Element Plus 见'对齐方式' Form 表单 | Element Plus 见'Form Attributes'
坑75(v-click-outside、element-plus、组件外点击触发、el-popover):尝试使用element-plus中封装的指令click-outside 。它功能是接收一个函数,当用户鼠标点击的区域在绑定指令的元素之外时,会触发该函数。
格式:v-click-outside:[绑定元素ref]='触发函数'
参考: 翻了翻element-ui源码,发现一个很实用的指令clickoutside - WahFung - 博客园 (cnblogs.com) vue2
vue3+ts实现自定义指令v-click-outside - 掘金 (juejin.cn) vue3
[Element Plus 源码解析 - 指令篇] click-outside 指令 - 掘金 (juejin.cn) vue3
找了找,该指令的源码在 src/utils 下的 clickoutside.js。
导入及注册,代码如下:
// main.js
import { createApp } from 'vue'
import App from './App.vue'
// 引入指令
import ClickOutside from 'element-plus/lib/directives/click-outside'
const app=createApp(App)
// 注册指令
app.directive('click-outside',ClickOutside)
使用:目标是点击el-popover弹出框之外时自动关闭el-popover。但因为el-popover在el-table-column中,使用有一定问题。
(具体场景介绍:在el-table中设置了一列放置操作按钮。点击操作按钮会显示el-popover。目标是两种情况下会关闭el-popover:点击其内部的'取消'按钮时和点击 el-popover 组件外时。)
代码如下:
// Index.vue
// 尝试一:使用失败,无效果
<el-table-column prop='operate' label='操作'>
<template #default='{ row,$index }'>
<el-popover :visible='showDelete[$index]' ref='removePopoverRef'
v-click-outside:[removePopoverRef]='cancelRemove($index)' >...</el-popover>
</el-popover>
</template>
</el-table-column>
// 尝试二:会warning
// 将指令移动到el-table-column上,用函数关闭全部el-popover
<el-table-column prop='operate' label='操作' v-click-outside:[removePopoverRef]='cancelRemove'>
...</el-table-column>
// cancelRemove()函数中会通过设置showDelete属性控制el-popover的隐藏
尝试一:使用失败,无效果报错:Runtime directive used on component with non-element root node. The directives will not function as intended. 在具有非元素根节点的组件上使用的运行时指令。指令将不会按预期发挥作用。
尝试二:有效果但warning:Maximum recursive updates exceeded in component <ElTable>. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.组件<eltable>中超过了最大递归更新数。这意味着你有一个反应效果,它会改变它自己的依赖关系,从而递归地触发它自己。可能的源包括组件模板、呈现函数、更新的钩子或监视器源函数。
ps:v-click-outside添加后会检测每一次点击,可以感受到运行变慢。
参考:Vue3疑问系列(2) — 在component vnode上绑定指令,指令是如何工作的? - 起源地 (qiyuandi.com)
于是对上一场景放弃v-click-outside的使用,采用解决方案见下方坑76(el-popover、click激活、点击取消隐藏、hide()、element-plus)。
坑76(el-popover、click激活、点击取消隐藏、hide()、element-plus):具体场景介绍:在el-table中设置了一列放置操作按钮。点击操作按钮会显示el-popover。目标是两种情况下会关闭el-popover:点击其内部的'取消'按钮时和点击 el-popover 组件外时。前缘见上方坑75(v-click-outside、element-plus、组件外点击触发、el-popover)。
发现el-popover使用非手动激活时(手动激活是绑定visible),可自动关闭。click激活,点击外部会自动关闭。于是修改方案。使用click激活,获取ref数组,点取消时用el-popover内置的 hide() 函数关闭。
参考: v-for 中的 Ref 数组 | Vue.js (vuejs.org)
解决多个el-popover点击确定/取消时,popover的隐藏问题_穆子航的博客-CSDN博客_el-popover 隐藏其中用的是 doClose() 函数,对应目前element-plus版本中的 hide() 函数
具体代码如下:
// 使用ref数组
<el-table-column prop='operate' label='操作'>
<template #default='{ row,$index }'>
<el-popover trigger='click' :ref='setRemovePopoverRefs'>
...
<el-button @click='cancelRemove($index)'>取消</el-button>
...
<template #reference>
...
</template>
</el-popover>
</template>
</el-table-column>
...
let removePopoverRefs=[]
const setRemovePopoverRefs=(el)=>{
if(removePopoverRefs.indexOf(el)===-1){
removePopoverRefs.push(el)
}
}
onBeforeUpdate(() => {
removePopoverRefs = []
})
const cancelRemove=(index)=>{ // 因为不是ref类型,直接调用属性,无需经过value
removePopoverRefs[index].hide()
}
by 莫得感情踩坑机(限定)
更多推荐
所有评论(0)