这是我参与「 第五届青训营 」伴学笔记创作活动的第 6 天
Form组件的开发
一、基本功能
1、数据校验,给用户正确或错误反馈
2、表单项:FormItem
二、样式编写
1、labelSize:改变表单的长度,提供sm、md、lg三种宽度选择
2、labelAlign:改变表单位置,start、center、end分别表示靠左、居中、靠右
三、表单校验
1、安装依赖
yarn add async-validator -S
2、创建input组件实现数据双向绑定触发校验、状态反馈和图标等
setup(props: InputProps, { emit }) {
// 注入校验方法
const formItem = inject('FORM_ITEM_CTX') as FormItemContext
const onInput = (e: Event) => {
const val = (e.target as HTMLInputElement).value
emit('update:modelValue', val)
formItem.validate()
}
}
})
3、这个Input的作用:
-
接收modelValue以及type绑定到内部的input当中
-
注入校验方法formItem
-
拿到当前input的value发送出去emit('update:modelValue', val)
-
执行校验方法
4、校验
-
当用户不需要校验时,应该默认返回true
-
存在四种情况:用户没有在表单中使用formItem、用户没有设置field、用户没有定义rules、定义了rules没有field
if (!formCtx) {
// formItem没有在表单中使用
console.warn('请在Form中使用FormItem')
return Promise.reject('请在Form中使用FormItem')
}
if (!props.field) {
console.warn('如果要校验当前项,请设置field字段')
return Promise.reject('如果要校验当前项,请设置field字段')
}
// 不需要校验
if (!formCtx.rules) {
return Promise.resolve({ result: true })
}
const itemRules = formCtx.rules[props.field] || undefined
if (!itemRules) {
return Promise.resolve({ result: true })
}
-
当用户需要校验时,获取校验规则和数值,使用Validator工具进行校验
// 获取校验规则和数值
const value = formCtx.model[props.field]
// 执行校验返回结果
const validator = new Validator({ [props.field]: itemRules })
return validator.validate({ [props.field]: value }, errors => {
if (errors) {
// 校验失败
showMessage.value = true
errorMessage.value = errors[0].message || '校验错误'
} else {
// 校验通过 清空
showMessage.value = false
errorMessage.value = ''
}
})
5、全局校验
-
想要点击某个按钮,比如登录,就自动调用校验方法进行校验
-
现存放待校验的items(Set)
const formItems = new Set<FormItemContext>()
-
如果有field就添加到数组中,否则不,所以需要定义添加和删除函数
const addItem = (item: FormItemContext) => formItems.add(item)
const removeItem = (item: FormItemContext) => formItems.delete(item)
-
挂载后注册到formCtx中
// 挂在后注册到formCtx中
onMounted(() => {
if (props.field) {
formCtx?.addItem(formItemCtx)
}
})
onUnmounted(() => {
if (props.field) {
formCtx?.removeItem(formItemCtx)
}
})
-
将validate提供给后代使用,定义参数valid,如果有就成功否则校验失败,在使用的vue中
const onLogin = () => {
loginForm.value.validate(valid => {
if (valid) {
alert('登录成功')
} else {
alert('校验失败,请重试!')
}
})
}