天天看點

【Vue 開發實戰】實戰篇 # 40:自己封裝一個支援自動校驗的表單項

說明

【Vue 開發實戰】學習筆記。

自定義表單控件

自定義或第三方的表單控件,也可以與 Form 元件一起使用。隻要該元件遵循以下的約定:

  • 提供受控屬性 value 或其它與 valuePropName-參數) 的值同名的屬性。
  • 提供 onChange 事件或 trigger-參數) 的值同名的事件。
  • 不能是函數式元件。

實作的元件效果

支援下拉選擇,然後自定義校驗該元件,送出能把選擇的資料傳遞到接口

【Vue 開發實戰】實戰篇 # 40:自己封裝一個支援自動校驗的表單項

不通過:

編寫元件

<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,) => {
                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>      

繼續閱讀