<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: () => (['支持中文、字母、数字']), } ] }收集message
getErrorInfo() { // 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 字段 },