mirror of
https://github.com/fugary/simple-element-plus-template.git
synced 2025-11-12 14:27:49 +00:00
表单验证简化
This commit is contained in:
@@ -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">
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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}格式校验不通过'
|
||||||
|
|||||||
@@ -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.'
|
||||||
|
|||||||
@@ -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: '',
|
||||||
|
|||||||
Reference in New Issue
Block a user