表单验证简化

This commit is contained in:
Gary Fu
2023-12-31 18:28:09 +08:00
parent a65a1db306
commit 7693635b45
6 changed files with 64 additions and 31 deletions

View File

@@ -9,16 +9,19 @@ import ControlChild from '@/components/common-form-control/control-child.vue'
* @property {'input'|'input-number'|'cascader'|'radio' * @property {'input'|'input-number'|'cascader'|'radio'
* |'radio-group'|'checkbox'|'checkbox-group'|'date-picker' * |'radio-group'|'checkbox'|'checkbox-group'|'date-picker'
* |'time-picker'|'switch'|'select'|'option'|'slider'|'transfer'|'upload'} type 类型 * |'time-picker'|'switch'|'select'|'option'|'slider'|'transfer'|'upload'} type 类型
* @property {any} value * @property {any} value 数据值
* @property {any} config * @property {string|[string]} prop 属性
* @property {string|[string]} prop * @property {string} label 标签
* @property {string} label
* @property {string} labelKey 用于国际化的label * @property {string} labelKey 用于国际化的label
* @property {boolean} required * @property {boolean} required 是否必填,后面解析成为rules的一部分
* @property {string} placeholder * @property {string|RegExp} pattern 正则表达式验证解析成为rules的一部分
* @property {string} patternMsg 正则表达式验证消息
* @property {boolean} disabled 禁用
* @property {boolean} readonly 只读
* @property {string} placeholder 占位提示符
* @property {{clearable:boolean,disabled:boolean,showPassword:boolean}} attrs * @property {{clearable:boolean,disabled:boolean,showPassword:boolean}} attrs
* @property {[CommonFormOption]} children 子节点 * @property {[CommonFormOption]} children 子节点
* @property {Array<RuleItem>} rules 子节点 * @property {Array<RuleItem>} rules 验证规则
*/ */
/** /**
@@ -42,7 +45,8 @@ const inputType = computed(() => {
}) })
const modelAttrs = computed(() => { const modelAttrs = computed(() => {
if (['input', 'select', 'autocomplete', 'cascader'].includes(inputType.value)) { console.info(inputType.value)
if (['input', 'select', 'autocomplete', 'cascader'].includes(props.option.type || 'input')) {
return Object.assign({ clearable: true }, props.option.attrs || {}) return Object.assign({ clearable: true }, props.option.attrs || {})
} }
return props.option.attrs return props.option.attrs
@@ -86,6 +90,8 @@ const modelValue = computed({
v-model="modelValue" v-model="modelValue"
v-bind="modelAttrs" v-bind="modelAttrs"
:placeholder="option.placeholder" :placeholder="option.placeholder"
:disabled="option.disabled"
:readonly="option.readonly"
@change="option.change" @change="option.change"
> >
<template v-if="option.children&&option.children.length"> <template v-if="option.children&&option.children.length">

View File

@@ -1,6 +1,7 @@
<script setup> <script setup>
import { computed } from 'vue' import { computed, ref } from 'vue'
import cloneDeep from 'lodash/cloneDeep' import cloneDeep from 'lodash/cloneDeep'
import { $i18nBundle } from '@/messages'
const props = defineProps({ const props = defineProps({
/** /**
@@ -22,18 +23,40 @@ const props = defineProps({
const rules = computed(() => { const rules = computed(() => {
const ruleResult = {} const ruleResult = {}
props.options.forEach(option => { props.options.forEach(option => {
if (option.prop && option.rules) { if (option.prop) {
ruleResult[option.prop] = cloneDeep(option.rules) let _rules = cloneDeep(option.rules || [])
if (option.required !== undefined) {
const label = option.label || $i18nBundle(option.labelKey)
_rules = [{
required: option.required,
trigger: 'blur',
message: $i18nBundle('common.msg.nonNull', [label])
}, ..._rules]
}
if (option.pattern !== undefined) {
const label = option.label || $i18nBundle(option.labelKey)
_rules = [{
pattern: option.pattern,
trigger: 'blur',
message: option.patternMsg || $i18nBundle('common.msg.patternInvalid', [label])
}, ..._rules]
}
if (_rules.length) {
ruleResult[option.prop] = _rules
}
} }
}) })
console.info(ruleResult) console.info('==============rules', ruleResult)
return ruleResult return ruleResult
}) })
const form = ref(null)
</script> </script>
<template> <template>
<el-form <el-form
ref="form"
:model="model" :model="model"
:rules="rules" :rules="rules"
:label-width="labelWidth" :label-width="labelWidth"
@@ -45,6 +68,10 @@ const rules = computed(() => {
:model="model" :model="model"
:option="option" :option="option"
/> />
<slot
name="default"
:form="form"
/>
</el-form> </el-form>
</template> </template>

View File

@@ -14,7 +14,7 @@ const menuItems = computed(() => {
}) })
const activeRoutePath = computed(() => { const activeRoutePath = computed(() => {
const route = useRoute() const route = useRoute()
return route.path !== '/' ? route.path : '' return route && route.path !== '/' ? route.path : ''
}) })
</script> </script>

View File

@@ -21,3 +21,7 @@ common.label.personalCenter = '个人中心'
common.label.personalInfo = '个人资料' common.label.personalInfo = '个人资料'
common.label.about = '关于' common.label.about = '关于'
common.label.logout = '退出' common.label.logout = '退出'
//* =======================msg=====================//
common.msg.nonNull = '{0}不能为空'
common.msg.patternInvalid = '{0}格式校验不通过'

View File

@@ -21,3 +21,7 @@ common.label.personalCenter = 'Personal Center'
common.label.personalInfo = 'Personal Info' common.label.personalInfo = 'Personal Info'
common.label.about = 'About' common.label.about = 'About'
common.label.logout = 'Logout' common.label.logout = 'Logout'
//* =======================msg=====================//
common.msg.nonNull = '{0} is required.'
common.msg.patternInvalid = '{0} pattern check failed.'

View File

@@ -9,12 +9,8 @@ const formOptions = [{
prop: 'userName', prop: 'userName',
value: '', value: '',
placeholder: '请输入用户名', placeholder: '请输入用户名',
required: true,
rules: [ rules: [
{
required: true,
message: '用户名不能为空',
trigger: 'blur'
},
{ {
min: 2, min: 2,
max: 6, max: 6,
@@ -27,22 +23,18 @@ const formOptions = [{
prop: 'userPassword', prop: 'userPassword',
value: '', value: '',
placeholder: '请输入密码', placeholder: '请输入密码',
rules: [ required: true,
{ pattern: /.{2,6}/,
required: true,
message: '密码不能为空',
trigger: 'blur'
},
{
min: 2,
max: 6,
message: '密码在2-6位之间',
trigger: 'blur'
}
],
attrs: { attrs: {
showPassword: true showPassword: true
} }
}, {
label: '出生日期',
type: 'date-picker',
prop: 'birthday',
value: '',
placeholder: '选择出生日期',
required: true
}] }]
const userDto = ref({ const userDto = ref({
userName: '', userName: '',