• ant design vue Modal 对话框和表单的使用


    https://www.antdv.com/components/modal-cn/

    对话框基本使用

    <template>
        <div>
            <a-button type="primary" @click="showModal">
                显示模态框
            </a-button>
            <a-modal
                    title="模态框标题"
                    :visible="visible"
                    :confirm-loading="confirmLoading"
                    @ok="handleOk"
                    @cancel="handleCancel"
            >
                <p>{{ ModalText }}</p>
            </a-modal>
        </div>
    </template>
    <script>
        export default {
            data() {
                return {
                    ModalText: 'Content of the modal',
                    visible: false,
                    confirmLoading: false,
                };
            },
            methods: {
                //显示模态框
                showModal() {
                    this.visible = true;
                },
                //点击ok
                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;
                },
            },
        };
    </script>
    

    效果

    image-20201117143920500

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

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

    例:

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

    效果

    image-20201117144235123

    对话框结合form表单使用

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

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

    <template>
        <div>
            <a-button type="primary" @click="showModal">
                显示模态框
            </a-button>
            <collection-create-form
                    ref="collectionForm"
                    :visible="visible"
                    @cancel="handleCancel"
                    @create="handleCreate"
            />
        </div>
    </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>
    

    效果

    image-20201117155754749

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

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

    方式二:组件绑定form

    <template>
        <div>
            <!--添加按钮和模态框-->
            <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>
        </div>
    </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>
    

    效果

    image-20201117175623176

    设置 确认按钮提交的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.

    image-20201117190428011

    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' })
    

    方式2:

    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 接管,这会导致以下结果:

    1. 不再需要也不应该onChange 来做同步,但还是可以继续监听 onChange 等事件。
    2. 你不能用控件的 value defaultValue 等属性来设置表单域的值,默认值可以用 getFieldDecoratorv-decorator 里的 initialValue
    3. 你不应该用 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=" 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>
    

    效果

    image-20201119110915605

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

    如:

    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=" 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>
    

    效果

    image-20201119113357626

  • 相关阅读:
    Element ui表单验证结束后再次打开清空验证信息
    oracle 新建用户 给用户设定权限
    oracle时间问题
    ORACLE 创建作业JOB例子
    ORACLE SQL PLUSE 创建作业 执行作业
    VS发布,签名出错 试图加载该页时出错,路径的形式不合法。
    Oracle 系统权限
    PL/SQL Developer 8.0 创建 Oracle Jobs 的疑惑
    信息系统系项目管理考试技巧
    水晶报表分组统计中如何让字段值居中显示
  • 原文地址:https://www.cnblogs.com/makalochen/p/13995637.html
Copyright © 2020-2023  润新知