摘要
正常情况下,如果我们想实现给每个 Form Item 添加提示,一般的UI设计如下图,一般都是类似于这样的在 label 后面添加一个图标,hover 显示对应的 Tip 内容。这样的话具体的代码实现如下。如果 Form 表单很多,这样就会导致这个文件的代码过于冗长。以此为初衷,下面我们将实现通过指令的方式在所有表单页为所需的表单项添加 Tip 提示组件。
<el-form-item prop='test'>
<template #label>
Label Name
<el-tooltip content="tipContent">
<el-icon><WarningFilled /></el-icon>
</el-tooltip>
</template>
</el-form-item>
指令实现
import { h, createApp } from 'vue'
import { ElTooltip, ElIcon } from 'element-plus'
import { InfoFilled } from '@element-plus/icons-vue'
import formTips from '@/const/formTips'
import store from '@/store'
function render(target, tip, cleanModal) {
const app = createApp({
render: () => h(
ElTooltip,
{
content: tip,
placement: 'top',
effect: 'dark',
enterable: false,
popperClass: 'common-tip-popper',
showAfter: 100,
hideAfter: 0,
},
{
default: () => h(ElIcon, {}, () => [h(InfoFilled)]),
},
),
})
const div = document.createElement('div')
div.classList.add('form-tip-icon')
cleanModal ? div.classList.add('hide') : div.classList.remove('hide')
app.mount(div)
// 查找是否已经存在
const exist = target.querySelector('.form-tip-icon')
exist && target.removeChild(exist)
target.appendChild(div)
}
export default {
beforeUpdate(el, bind) {
const { value } = bind
const { cleanModal, language } = store.getters
if (!value) return
requestIdleCallback(() => {
Array.from(el.children).forEach((item, index) => {
const target = item.querySelector('.el-form-item__label')
target && formTips[value][index] && render(target, formTips[value][index], cleanModal)
})
})
},
}
指令使用
<el-form :model="drawerForm" label-position="top" v-addFormTips="'form1'">
</el-form>
FormTips 文件
按顺序添加表单项的Tip文本,如果没有请填写false,如果是TypeScript的话就填空字符串,以防做了校验。formTips 的 key 值为对应模块使用指令时传入的值.
const formTips = {
form1: [],
form2: [],
form3: [],
}
export default formTips