前提
发现antd vue和element plus的官网都没有自定义表单项组件的文档, 参考老版本的文档写, 又无效, 经过一段时间的摸索, 终于有了一个有效的解决办法, 遂在此记录
定义自定义表单项组件
请一定要注意查看代码中的注释.
MyComp.vue
<template>
<a-button @click="onClick">按钮</a-button>
内部: {{ data }}
</template>
<script lang="ts">
import {defineComponent, ref, toRefs, watch} from "vue";
export default defineComponent({
props: {
// 注意: 这里之所以声明一个id, 是因为 ant design vue 2.x 的表单项组件会自动传传过来, 如果不定义, 那么控制台会出现一大片警告
id: String,
// 注意: 这里的value和update:value, 是构成 v-model:value的要素, 之所以用value而不是modelValue是为了和ant design vue2.x保持一致
value: String
},
emits: {
// 注意: 当定义了emits选项之后, 所有的context.emit的事件, 都应该在这里声明一次, 否则编译器会提示错误
'update:value': (val: string) => {
return true;
},
change: (val: string) => {
return true;
},
// 如果作为ant design of vue的表单项如果没声明这个, 也会出现大片警告, 当前这个emit在这个组件中并未用上
blur: (val: string) => {
return true;
}
},
setup(props, context) {
const {value} = toRefs(props)
const data = ref<string>()
watch(value, () => {
// 监听外部传入的value的变化, 将value的变化传递给data
data.value = value.value
})
const onClick = () => {
data.value = '张三'
// 发出这个事件, 是为了触发vue的v-model, 执行双向绑定
context.emit('update:value', data.value)
// 发出这个事件, 是为了能够触发 ant design vue 的自定义验证
context.emit('change', data.value)
}
return {onClick, data}
}
})
</script>
Test.vue
<template>
<a-form :model="formDataRef" ref="formRef">
<a-form-item label="标题" name="title" :rules="nameRules">
<a-input v-model:value="formDataRef.title"/>
</a-form-item>
<!-- 这里使用的就是自定义表单组件 -->
<a-form-item label="我的值" name="myVal" :rules="myValRules">
<MyComp v-model:value="formDataRef.myVal"></MyComp>
</a-form-item>
</a-form>
<a-button @click="onClick">获取表单数据</a-button>
<a-button @click="onChangeFormData">外部直接修改表单数据</a-button>
</template>
<script lang="ts">
import {defineComponent, reactive, ref, toRaw} from "vue";
import MyComp from "@/MyComp.vue";
import {RuleObject, ValidateErrorEntity} from "ant-design-vue/es/form/interface";
interface FormData {
title: string,
myVal: string
}
export default defineComponent({
setup() {
const formRef = ref();
const formData: FormData = {title: '', myVal: ''}
const formDataRef = reactive<FormData>(formData);
const checkName = (rule: RuleObject, value: string) => {
console.log('执行 checkName 验证', rule, value)
return Promise.resolve();
}
const checkMyVal = (rule: RuleObject, value: string) => {
console.log('执行 checkMyVal 验证', rule, value)
return Promise.resolve();
}
const myValRules = [{
trigger: 'change',
validator: checkMyVal
}]
const nameRules = [{
trigger: 'change',
validator: checkName
}]
const onClick = () => {
formRef.value
.validate()
.then(() => {
const obj = toRaw(formDataRef)
console.log('values', formDataRef, obj);
})
.catch((error: ValidateErrorEntity<FormData>) => {
console.log('error', error);
});
}
const onChangeFormData = () => {
formDataRef.myVal = '改了myVal'
formDataRef.title = '改了title'
console.log('外部改变值formDataRef')
// 直接修改 formDataRef.myVal 的值, 并不会自动触发 myVal的验证, 因此需要手动触发一次
formRef.value.validateFields('myVal')
}
return {formRef, formDataRef, onClick, myValRules, nameRules, onChangeFormData}
},
components: {MyComp}
})
</script>
<style lang="less" scoped>
</style>