表单验证简化

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'
* |'radio-group'|'checkbox'|'checkbox-group'|'date-picker'
* |'time-picker'|'switch'|'select'|'option'|'slider'|'transfer'|'upload'} type 类型
* @property {any} value
* @property {any} config
* @property {string|[string]} prop
* @property {string} label
* @property {any} value 数据值
* @property {string|[string]} prop 属性
* @property {string} label 标签
* @property {string} labelKey 用于国际化的label
* @property {boolean} required
* @property {string} placeholder
* @property {boolean} required 是否必填,后面解析成为rules的一部分
* @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 {[CommonFormOption]} children 子节点
* @property {Array<RuleItem>} rules 子节点
* @property {Array<RuleItem>} rules 验证规则
*/
/**
@@ -42,7 +45,8 @@ const inputType = 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 props.option.attrs
@@ -86,6 +90,8 @@ const modelValue = computed({
v-model="modelValue"
v-bind="modelAttrs"
:placeholder="option.placeholder"
:disabled="option.disabled"
:readonly="option.readonly"
@change="option.change"
>
<template v-if="option.children&&option.children.length">

View File

@@ -1,6 +1,7 @@
<script setup>
import { computed } from 'vue'
import { computed, ref } from 'vue'
import cloneDeep from 'lodash/cloneDeep'
import { $i18nBundle } from '@/messages'
const props = defineProps({
/**
@@ -22,18 +23,40 @@ const props = defineProps({
const rules = computed(() => {
const ruleResult = {}
props.options.forEach(option => {
if (option.prop && option.rules) {
ruleResult[option.prop] = cloneDeep(option.rules)
if (option.prop) {
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
})
const form = ref(null)
</script>
<template>
<el-form
ref="form"
:model="model"
:rules="rules"
:label-width="labelWidth"
@@ -45,6 +68,10 @@ const rules = computed(() => {
:model="model"
:option="option"
/>
<slot
name="default"
:form="form"
/>
</el-form>
</template>

View File

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

View File

@@ -21,3 +21,7 @@ common.label.personalCenter = '个人中心'
common.label.personalInfo = '个人资料'
common.label.about = '关于'
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.about = 'About'
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',
value: '',
placeholder: '请输入用户名',
rules: [
{
required: true,
message: '用户名不能为空',
trigger: 'blur'
},
rules: [
{
min: 2,
max: 6,
@@ -27,22 +23,18 @@ const formOptions = [{
prop: 'userPassword',
value: '',
placeholder: '请输入密码',
rules: [
{
required: true,
message: '密码不能为空',
trigger: 'blur'
},
{
min: 2,
max: 6,
message: '密码在2-6位之间',
trigger: 'blur'
}
],
pattern: /.{2,6}/,
attrs: {
showPassword: true
}
}, {
label: '出生日期',
type: 'date-picker',
prop: 'birthday',
value: '',
placeholder: '选择出生日期',
required: true
}]
const userDto = ref({
userName: '',