天天看點

【Vue 開發實戰】實戰篇 # 38:表單初始資料、自動校驗、動态指派

說明

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

ant design vue 跟 elementui 的表單校驗差別

ant design vue 的表單設計模式是自動校驗不能使用雙向綁定,而是将資料托管給 form,form 就像一個黑盒,裡面的資料不會影響到其他的資料,如果需要資料同步到其他元件,需要調用 form 提供的 api 進行擷取。

比對圖如下:

【Vue 開發實戰】實戰篇 # 38:表單初始資料、自動校驗、動态指派
【Vue 開發實戰】實戰篇 # 38:表單初始資料、自動校驗、動态指派

v-decorator 指令

​​https://github.com/vueComponent/ant-design-vue/blob/1.x/components/_util/FormDecoratorDirective.js​​

export function antDecorator(Vue) {
  return Vue.directive('decorator', {});
}

export default {
  // just for tag
  install: Vue => {
    antDecorator(Vue);
  },
};      

修改手動校驗的表單

<template>
    <a-form :layout="formLayout" :form="form">
        <a-form-item
            label="Form Layout"
            :label-col="formItemLayout.labelCol"
            :wrapper-col="formItemLayout.wrapperCol"
        >
            <a-radio-group
                default-value="horizontal"
                @change="handleFormLayoutChange"
            >
                <a-radio-button value="horizontal"> Horizontal </a-radio-button>
                <a-radio-button value="vertical"> Vertical </a-radio-button>
                <a-radio-button value="inline"> Inline </a-radio-button>
            </a-radio-group>
        </a-form-item>
        <a-form-item
            label="Field A"
            :label-col="formItemLayout.labelCol"
            :wrapper-col="formItemLayout.wrapperCol"
        >
            <a-input v-decorator="[
                'fieldA',
                {
                    initialValue: fieldA,
                    rules: [
                        {
                            required: true,
                            min: 6,
                            message: '必須大于5個字元'
                        }
                    ]
                },
            ]" placeholder="input placeholder" />
        </a-form-item>
        <a-form-item
            label="Field B"
            :label-col="formItemLayout.labelCol"
            :wrapper-col="formItemLayout.wrapperCol"
        >
            <a-input v-decorator="['fieldB']" placeholder="input placeholder" />
        </a-form-item>
        <a-form-item :wrapper-col="buttonItemLayout.wrapperCol">
            <a-button type="primary" @click="handleSubmit"> Submit </a-button>
        </a-form-item>
    </a-form>
</template>

<script>export default {
    data() {
        this.form = this.$form.createForm(this);
        return {
            formLayout: "horizontal",
            fieldA: "hello kaimo",
            fieldB: "",
        };
    },
    computed: {
        formItemLayout() {
            const { formLayout } = this;
            return formLayout === "horizontal"
                ? {
                      labelCol: { span: 4 },
                      wrapperCol: { span: 14 },
                  }
                : {};
        },
        buttonItemLayout() {
            const { formLayout } = this;
            return formLayout === "horizontal"
                ? {
                      wrapperCol: { span: 14, offset: 4 },
                  }
                : {};
        },
    },
    mounted() {
        // 動态指派
        setTimeout(() => {
            this.form.setFieldsValue({
                fieldB: "kaimo313"
            })
        }, 2000)
    },
    methods: {
        handleFormLayoutChange(e) {
            this.formLayout = e.target.value;
        },
        handleSubmit() {
            // 自動校驗
            this.form.validateFields((err,) => {
                console.log(err, values)
                if(!err) {
                    console.log(values);
                }
            })
        },
    },
};</script>      

效果

繼續閱讀