说明
【Vue 开发实战】学习笔记。
自定义表单控件
自定义或第三方的表单控件,也可以与 Form 组件一起使用。只要该组件遵循以下的约定:
- 提供受控属性 value 或其它与 valuePropName-参数) 的值同名的属性。
- 提供 onChange 事件或 trigger-参数) 的值同名的事件。
- 不能是函数式组件。
实现的组件效果
支持下拉选择,然后自定义校验该组件,提交能把选择的数据传递到接口不通过:
编写组件
新建 ant-design-vue-pro\src\components\ReceiverAccount.vue
<template> <a-input-group compact> <a-select v-model="type" style="width: 120px;" @change="handleTypeChange"> <a-select-option value="alipay">支付宝</a-select-option> <a-select-option value="bank">银行账户</a-select-option> </a-select> <a-input style="width: calc(100% - 120px);" v-model="number" @change="handleNumberChange"/> </a-input-group> </template> <script> export default { props: { value: { type: Object, }, }, data() { const { type, number } = this.value; return { type: type || "alipay", number: number || "" }; }, watch: { value(val) { // 同步给 type、number Object.assign(this, val); } }, methods: { handleTypeChange(val) { this.$emit("change", { ...this.value, type: val }); }, handleNumberChange(e) { this.$emit("change", { ...this.value, number: e.target.value }); } }, }; </script> <style></style>
表单的 vuex 添加状态
const state = { step: { payAccount: "kaimo313", receiverAccount: { type: "alipay", number: "" } } }
在 Step1 组件里使用
<template> <div> <a-form layout="horizontal" :form="form"> <a-form-item label="付款账号" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" > <a-input v-decorator="[ 'payAccount', { initialValue: step.payAccount, rules: [ { required: true, message: '请输入付款账号' } ] }, ]" placeholder="请输入付款账号" /> </a-form-item> <a-form-item label="收款账号" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" > <ReceiverAccount v-decorator="[ 'receiverAccount', { initialValue: step.receiverAccount, rules: [ { required: true, message: '请输入收款账号', validator: (rule, value, callback) => { if(value && value.number) { callback(); }else{ callback('收款账号没有填写'); } } }, ] }, ]"/> </a-form-item> <a-form-item> <a-button type="primary" @click="handleSubmit">下一步</a-button> </a-form-item> </a-form> </div> </template> <script> import ReceiverAccount from "@/components/ReceiverAccount.vue"; export default { data() { this.form = this.$form.createForm(this); return { formItemLayout:{ labelCol: { span: 4 }, wrapperCol: { span: 14 }, } }; }, components: { ReceiverAccount }, computed: { step() { return this.$store.state.form.step } }, created() { console.log("this.$store---->", this.$store) }, methods: { handleSubmit() { const { form, $router, $store} = this; form.validateFields((err, values) => { console.log(err, values) if(!err) { console.log(values); $store.commit({ type: "form/saveStepFormData", payload: values }); $router.push("/form/step-form/confirm"); } }) } }, }; </script> <style></style>