handleOk(e) { this.ModalText = 'The modal will be closed after two seconds'; this.confirmLoading = true; setTimeout(() => { this.visible = false; this.confirmLoading = false; }, 2000); //点击cancel handleCancel(e) { console.log('Clicked cancel button'); this.visible = false;

设置对话框确认和取消按钮的文字

ok-text : 设置确认按钮文字
cancel-text : 设置取消按钮文字

<a-modal
        title="模态框标题"
        ok-text="确认" 
        cancel-text="取消"
        :visible="visible"
        :confirm-loading="confirmLoading"
        @ok="handleOk"
        @cancel="handleCancel"

对话框结合form表单使用

https://www.antdv.com/components/form-cn/#components-form-demo-form-in-modal-to-create

方式1:自定义组件模板的方式

<template>
        <a-button type="primary" @click="showModal">
            显示模态框
        </a-button>
        <collection-create-form
                ref="collectionForm"
                :visible="visible"
                @cancel="handleCancel"
                @create="handleCreate"
</template>
<script>
    const CollectionCreateForm = {
        props: ['visible'],
        beforeCreate() {
            this.form = this.$form.createForm(this, { name: 'form_in_modal' });
        template: `
            <a-modal
                    :visible="visible"
                    title='模态框标题'
                    okText='确认'
                    cancel-text="取消"
                    @cancel="() => { $emit('cancel') }"
                    @ok="() => { $emit('create') }"
                <a-form layout='vertical' :form="form">
                    <a-form-item label='Title'>
                        <a-input
                                v-decorator="[
                                      'title',
                                        rules: [{ required: true, message: 'title必填!' }],
                    </a-form-item>
                    <a-form-item label='Description'>
                        <a-input
                                type='textarea'
                                v-decorator="['description']"
                    </a-form-item>
                    <a-form-item class='collection-create-form_last-form-item'>
                        <a-radio-group
                                v-decorator="[
                                  'modifier',
                                        initialValue: 'private',
                            <a-radio value='public'>Public</a-radio>
                            <a-radio value='private'>Private</a-radio>
                        </a-radio-group>
                    </a-form-item>
                </a-form>
            </a-modal>
    export default {
        components: { CollectionCreateForm },
        data() {
            return {
                visible: false,
        methods: {
            //显示模态框
            showModal() {
                this.visible = true;
            //关闭模态框
            handleCancel() {
                this.visible = false;
            //点击确认
            handleCreate() {
                const form = this.$refs.collectionForm.form;
                form.validateFields((err, values) => {
                    if (err) {
                        return;
                    console.log('form 表单内容: ', values);
                    form.resetFields();
                    this.visible = false;
</script>

注意:这种方式需要支持template选项

报错参考:https://www.cnblogs.com/makalochen/p/13994493.html

方式二:组件绑定form

<template>
        <!--添加按钮和模态框-->
        <a-button type="primary" @click="showModal">
        </a-button>
        <a-modal
                :visible="visible"
                :title= "modelTitle"
                okText='确认'
                cancel-text="取消"
                @cancel="handleCancel"
                @ok="handleOk"
            <!--表单 并将表单的值绑定到this.from-->
            <a-form layout='vertical' :form="form">
                <!--每一项元素-->
                <a-form-item label='用户名'>
                    <a-input
                            v-decorator="[
                                      'username',
                                        rules: [{ required: true, message: '请填写登录用户名!' }],
                </a-form-item>
                <a-form-item label='密码'>
                    <a-input
                            type='password'
                            v-decorator="[
                                      'password',
                                        rules: [{ required: true, message: '请填写登录密码!' }],
                </a-form-item>
                <a-form-item label="状态">
                    <a-radio-group
                            v-decorator="[
                                  'status',
                                        initialValue: '1',
                        <a-radio value='1'>启用</a-radio>
                        <a-radio value='0'>禁用</a-radio>
                    </a-radio-group>
                </a-form-item>
            </a-form>
        </a-modal>
</template>
<script>
    export default {
        //el 创建前
        beforeCreate() {
            //创建表单
            this.form = this.$form.createForm(this, { name: 'form_in_modal' });
        data() {
            return {
                visible: false,
                //模态对话框标题
                modelTitle: '模态框标题',
        methods: {
            //显示模态框
            showModal() {
                this.visible = true;
            //关闭模态框
            handleCancel() {
                this.visible = false;
            //点击确认
            handleOk() {
                const form = this.form;
                form.validateFields((err, values) => {
                    if (err) {
                        return;
                    console.log('form 表单内容: ', values);
                    form.resetFields();
                    this.visible = false;
</script>

设置 确认按钮提交的loading

<!--对话框--> <a-modal :visible="visible" :title= "modelTitle" :confirm-loading="confirmLoading" okText='确认' cancel-text="取消" @cancel="handleCancel" @ok="add" data() 设置 //true表示loading,反之则使用false confirmLoading: false,

设置model的表单项

//设置模态框的form表单的值
this.$nextTick(()=>{
    setTimeout(() => {
        this.form.setFieldsValue({
            username : record.username,
            password : record.password,
            status : record.status

设置表单项报错的问题

Warning: You cannot set a form field before rendering a field associated with the value.

https://www.cnblogs.com/cirry/p/12483131.html

在用ant-design-vue的框架中,使用到了这种场景,就是点击编辑按钮,弹出modal模态框,渲染modal模态框中的form表单页面,并给表单赋值,但是在给表单赋值的时候,总是会报错。

错误提示: Warning: You cannot set a form field before rendering a field associated with the value.

经过一番查找后发现,造成这种原因一般有以下几个原因:

1.使用了表单的方法setFieldsValue(),来设置一组输入控件的值,传入的值为object,但是传入的值要和表单的值一一对应,能少传不能多传。

遇到这种情况的解决方式为:form渲染需要什么值你就传什么值

方式1:一个一个传

 this.form.setFieldsValue({ note: '123', mark: '456' })
add (record) {  //record:需要引用的值
   this.visible = true
   this.mdl = Object.assign({}, record)  // 浅拷贝
   this.form.setFieldsValue(pick(this.mdl, 'note', 'mark'))  // loadsh的pick方法

但是你会发现这么些还是报同样的错误。按照错误提示的原意:不能在表单渲染之前赋值

2.调用setFieldsValue()方法,需要放在$nextTick()函数中执行,改为如下即可:

this.$nextTick(()=>{
    this.form.setFieldsValue(pick(this.mdl, 'note', 'mark'))  // loadsh的pick方法

一般到这里就能解决问题了,如果还在报同样的错误,那就这样吧:

3.再放到setTimeout()方法中

this.$nextTick(() => {
     setTimeout(() => {
     this.form.setFieldsValue(pick(this.mdl, 'note', 'mark'))  // loadsh的pick方法

关于form表单使用v-decorator绑定了默认值不能修改的问题

this.form.getFieldDecorator(id, options) 和 v-decorator="[id, options]" #

经过 getFieldDecoratorv-decorator 包装的控件,表单控件会自动添加 value(或 valuePropName 指定的其他属性) onChange(或 trigger 指定的其他属性),数据同步将被 Form 接管,这会导致以下结果:

  • 不再需要也不应该onChange 来做同步,但还是可以继续监听 onChange 等事件。
  • 你不能用控件的 value defaultValue 等属性来设置表单域的值,默认值可以用 getFieldDecoratorv-decorator 里的 initialValue
  • 你不应该用 v-model,可以使用 this.form.setFieldsValue 来动态改变表单值。
  • 使用form表单是不能修改的,推荐使用FormModel表单,而且v2版本也移除了form表单,保留了formModel表单:

    https://2x.antdv.com/docs/vue/migration-v2-cn/

    组件重构 #

    在 1.x 中我们提供了 Form、FormModel 两个表单组件,原有的 Form 组件使用 v-decorator 进行数据绑定,在 Vue2 中我们通过上下文进行强制更新组件,但是在 Vue3 中,由于引入 patchFlag 等优化方式,强制刷新会破坏 patchFlag 带来的性能优势。所以在 2.0 版本中我们将 Form、FormModel 进行合并,保留了 FormModel 的使用方式,丰富了相关功能,并改名成 Form。

    FormModel表单使用

    FormModel表单: https://www.antdv.com/components/form-model-cn/

    基本使用:

    <template>
        <a-form-model :model="form" :label-col="labelCol" :wrapper-col="wrapperCol">
            <a-form-model-item label="Activity name">
                <a-input v-model="form.name" />
            </a-form-model-item>
            <a-form-model-item label="Activity zone">
                <a-select v-model="form.region" placeholder="please select your zone">
                    <a-select-option value="shanghai">
                        Zone one
                    </a-select-option>
                    <a-select-option value="beijing">
                        Zone two
                    </a-select-option>
                </a-select>
            </a-form-model-item>
            <a-form-model-item label="Activity time">
                <a-date-picker
                        v-model="form.date1"
                        show-time
                        type="date"
                        placeholder="Pick a date"
                        style="width: 100%;"
            </a-form-model-item>
            <a-form-model-item label="Instant delivery">
                <a-switch v-model="form.delivery" />
            </a-form-model-item>
            <a-form-model-item label="Activity type">
                <a-checkbox-group v-model="form.type">
                    <a-checkbox value="1" name="type">
                        Online
                    </a-checkbox>
                    <a-checkbox value="2" name="type">
                        Promotion
                    </a-checkbox>
                    <a-checkbox value="3" name="type">
                        Offline
                    </a-checkbox>
                </a-checkbox-group>
            </a-form-model-item>
            <a-form-model-item label="Resources">
                <a-radio-group v-model="form.resource">
                    <a-radio value="1">
                        Sponsor
                    </a-radio>
                    <a-radio value="2">
                        Venue
                    </a-radio>
                </a-radio-group>
            </a-form-model-item>
            <a-form-model-item label="Activity form">
                <a-input v-model="form.desc" type="textarea" />
            </a-form-model-item>
            <a-form-model-item :wrapper-col="{ span: 14, offset: 4 }">
                <a-button type="primary" @click="onSubmit">
                    Create
                </a-button>
                <a-button style="margin-left: 10px;">
                    Cancel
                </a-button>
            </a-form-model-item>
        </a-form-model>
    </template>
    <script>
        export default {
            data() {
                return {
                    labelCol: { span: 4 },
                    wrapperCol: { span: 14 },
                    form: {
                        name: '',
                        region: undefined,
                        date1: undefined,
                        delivery: false,
                        type: [],
                        resource: '',
                        desc: '',
            methods: {
                onSubmit() {
                    console.log('submit!', this.form);
    </script>
    

    注意:双向绑定切换需要使用字符串的形式,就算是数值也需要,

    status : '1'
    this.form.status = ''+record.status;
    

    表单验证 #

    Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 FormItemprop 属性设置为需校验的字段名即可。校验规则参见 async-validator

    <template>
        <a-form-model
                ref="ruleForm"
                :model="form"
                :rules="rules"
                :label-col="labelCol"
                :wrapper-col="wrapperCol"
            <a-form-model-item ref="name" label="Activity name" prop="name">
                <a-input
                        v-model="form.name"
                        @blur="
              () => {
                $refs.name.onFieldBlur();
            </a-form-model-item>
            <a-form-model-item label="Activity zone" prop="region">
                <a-select v-model="form.region" placeholder="please select your zone">
                    <a-select-option value="shanghai">
                        Zone one
                    </a-select-option>
                    <a-select-option value="beijing">
                        Zone two
                    </a-select-option>
                </a-select>
            </a-form-model-item>
            <a-form-model-item label="Activity time" required prop="date1">
                <a-date-picker
                        v-model="form.date1"
                        show-time
                        type="date"
                        placeholder="Pick a date"
                        style="width: 100%;"
            </a-form-model-item>
            <a-form-model-item label="Instant delivery" prop="delivery">
                <a-switch v-model="form.delivery" />
            </a-form-model-item>
            <a-form-model-item label="Activity type" prop="type">
                <a-checkbox-group v-model="form.type">
                    <a-checkbox value="1" name="type">
                        Online
                    </a-checkbox>
                    <a-checkbox value="2" name="type">
                        Promotion
                    </a-checkbox>
                    <a-checkbox value="3" name="type">
                        Offline
                    </a-checkbox>
                </a-checkbox-group>
            </a-form-model-item>
            <a-form-model-item label="Resources" prop="resource">
                <a-radio-group v-model="form.resource">
                    <a-radio value="1">
                        Sponsor
                    </a-radio>
                    <a-radio value="2">
                        Venue
                    </a-radio>
                </a-radio-group>
            </a-form-model-item>
            <a-form-model-item label="Activity form" prop="desc">
                <a-input v-model="form.desc" type="textarea" />
            </a-form-model-item>
            <a-form-model-item :wrapper-col="{ span: 14, offset: 4 }">
                <a-button type="primary" @click="onSubmit">
                    Create
                </a-button>
                <a-button style="margin-left: 10px;" @click="resetForm">
                    Reset
                </a-button>
            </a-form-model-item>
        </a-form-model>
    </template>
    <script>
        export default {
            data() {
                return {
                    labelCol: { span: 4 },
                    wrapperCol: { span: 14 },
                    other: '',
                    form: {
                        name: '',
                        region: undefined,
                        date1: undefined,
                        delivery: false,
                        type: [],
                        resource: '',
                        desc: '',
                    rules: {
                        name: [
                            { required: true, message: 'Please input Activity name', trigger: 'blur' },
                            { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
                        region: [{ required: true, message: 'Please select Activity zone', trigger: 'change' }],
                        date1: [{ required: true, message: 'Please pick a date', trigger: 'change' }],
                        type: [
                                type: 'array',
                                required: true,
                                message: 'Please select at least one activity type',
                                trigger: 'change',
                        resource: [
                            { required: true, message: 'Please select activity resource', trigger: 'change' },
                        desc: [{ required: true, message: 'Please input activity form', trigger: 'blur' }],
            methods: {
                onSubmit() {
                    this.$refs.ruleForm.validate(valid => {
                        if (valid) {
                            alert('submit!');
                        } else {
                            console.log('error submit!!');
                            return false;
                resetForm() {
                    this.$refs.ruleForm.resetFields();
    </script>