闽公网安备 35020302035485号

<template>
<div class="el-form-item">
.....
</div>
</template>
<script>
import { FormItem } from 'element-ui'
export default {
extends: FormItem,
name: 'form-item-tip'
}
</script>
收集提示信息rules:{
FucName: [
{
required: true,
message: '名称不能为空',
trigger: ['change'],
},
{
validator: this.validLen,
trigger: ['change'],
message: ['支持长度为6-10个字符'],
},
{
validator: this.validAll,
trigger: ['change'],
message: () => (['支持中文、字母、数字']),
}
]
}
收集messagegetErrorInfo() {
// tip 状态
const mesErrorObj = {}
this.tipList.forEach((item) => {
mesErrorObj[item.message] = item.isError
})
// 获取最新规则数组
const curRules = this.getRules()
this.tipList = curRules.reduce((acc, cur) => {
const message = cur.message
if (Array.isArray(message)) {
return this.handlerArray(acc, message, mesErrorObj)
}
if (typeof message === 'function') {
return this.handlerArray(acc, message(), mesErrorObj)
}
return [
...acc,
{
// 优先使用上一次状态
isError: mesErrorObj[message] === undefined ? true : mesErrorObj[message],
message,
},
]
}, [])
},
注:一个自定义规则 a 若返回三种提示信息,这种需要拆分为三个自定义规则,因为 a 返回规则1不符合时,规则2、3 是否符合无从得知(使用时需要额外注意)<template>
<div class="el-form-item">
.....
<div class="el-form-item__content" :style="contentStyle">
<el-popover trigger="focus">
<!-- 支持插槽 -->
<slot name="tip" :tipList="tipList">
<div class="tip-wrap">
<div class="tip-item" v-for="(item, index) in tipList" :key="index">
<i :class="[item.isError ? 'el-icon-error icon-error' : 'el-icon-success icon-success']"></i>
<span>{{ item.message }}</span>
</div>
</div>
</slot>
<slot slot="reference"></slot>
</el-popover>
</div>
</div>
</template>
聚焦触发校验<el-popover @show="showPopover" ref="popoverRef"></el-popover>
updatePopover() {
this.$nextTick(() => {
this.$refs.popoverRef.updatePopper()
})
},
showPopover() {
this.getErrorInfo()
this.validate('', noop)
this.updatePopover()
},
非必填情况<el-popover :disabled="popoverDisable" ref="popoverRef"></el-popover>
computed: {
popoverDisable() {
return !this.tipList.length || (this.tipList.length && !this.isRequired && this.fieldValueIsEmpty)
},
fieldValueIsEmpty() {
return (
this.fieldValue === '' || this.fieldValue === null || this.fieldValue === undefined || (Array.isArray(this.fieldValue) && this.fieldValue.length === 0)
)
},
},
watch: {
popoverDisable(nVal, oVal) {
if (!nVal && oVal) {
// 从禁用到展示 -- 需要更新位置
this.updatePopover()
} else {
// 从展示到禁用 -- 规则都符合
this.validateState = 'success'
}
},
},
校验以及结果展示async-validataor 结果(特殊处理情况:必填情况下,值为空
.包含
必填规则 message// 重写
validate(trigger, callback = noop) {
this.validateDisabled = false
const rules = this.getFilteredRule(trigger)
.....
if (this.popoverDisable) {
callback('', null)
return
}
...
if (rules && rules.length > 0) {
rules.forEach((rule) => {
delete rule.trigger
if (rule.validator) {
delete rule.message
}
})
}
....
validator.validate(model, { firstFields: false }, (errors, invalidFields) => {
....
this.tipAllMessage(errors)
})
},
// 更新提示信息状态
tipAllMessage(errors) {
let errorMes = Array.isArray(errors) ? errors.map((item) => item.message) : []
if (this.isRequired && this.fieldValueIsEmpty) {
// 必填情况下,值为空,特殊处理
errorMes = this.tipList
.filter((item) => {
// 其他配置规则 --- 留下
if (!item.isValidator) {
return true
}
// async-validataor 结果中有的 --- 留下
if (errorMes.includes(item.message)) {
return true
}
return false
})
.map((item) => item.message)
}
// errorMes 中存在的没通过,否则通过 --- 更新 tipList 中 isError 字段
},