做个可复用弹窗表单吧

昨天弄了个可复用的表单,今天就把它放进弹窗里面吧,好多小伙伴儿想必都做过类似的事情,总是需要列表编辑或者添加数据,然后弹出一个表单,进行编辑,然后提交后台,今天我们就来封装一下,下次再做,就配置一下数据就轻松生成一个表单弹窗,多好。先上个图给你们:


QQ截图20201119145507.png

怎么样,看上去是不是还不错呢。
表单封装我就不说了,上一篇有讲过。今天就给表单加一个提交后清空重置表单的方法就好了。
在我们的表单组件methods里面先写一个

//重置表单初始数据并移除校验效果
resetForm(){
  this.$refs['customForm'].resetFields();
},

然后我们先再来封装弹窗表单组件。和表格弹窗差不多,我们先把弹窗的属性props定义好,然后给弹窗里面添加一个表单需要用到的数据对象dialogForm。这里我们注意,要把封装好的表单里面isHandle的操作栏属性为false,因为弹窗带了操作栏,我们利用这个操作栏来进行业务回调。
其他的弹窗属性和方法与表格弹窗基本一致。

<template>
    <div>
        <el-dialog
          :title="title"
          :visible.sync="dialogVisible"
          :width="width"
            :center="isCenter"
            :fullscreen="isFull"
            :destroy-on-close="true"
          >
            <!-- :before-close="handleClose" 弹窗关闭前的回调-->
            <!-- 这里是表单组件,通过接受父组件数据熏染单 -->
            <custom-form :myForm="dialogForm.myForm" :isHandle="false" :formData="dialogForm.formData" ref="dynamic" :inline="false" v-on="$listeners">
            </custom-form>
          <span slot="footer" class="dialog-footer">
            <el-button @click="dialogVisible = false">取 消</el-button>
            <el-button :loading="vLoading" type="primary" @click="clickDialog">确 定</el-button>
          </span>
        </el-dialog>
    </div>
</template>

<script>
import CustomForm from '@/mycomponents/CustomForm/index.vue'
export default {
    inheritAttrs:false,
    components:{
        CustomForm
    },
    props:{
        //确定按钮loading
        loading:{
            type:Boolean,
            default:false,
        },
        //表单需要用到的数据
        dialogForm:{
            type:Object,
            default:()=>{}
        },
        //窗口可见状态
        visible:{
            type:Boolean,
            default:false,
        },
        //弹窗标题
        title:{
            type:String,
            default:'标题'
        },
        //弹窗宽度
        width:{
            type:String,
            default:'50%'
        },
        //弹窗是否居中
        isCenter:{
            type:Boolean,
            default:false
        },
        //弹窗是否全局显示
        isFull:{
            type:Boolean,
            default:false
        },
    },
    computed:{
        dialogVisible: {
            get() {
                return this.visible
            },
            set(val) {
                this.$emit('update:visible', val)
            }
        },
        //确定按钮loading事件
        vLoading: {
            get() {
                return this.loading
            },
            set(val) {
                this.$emit('update:load', val)
            }
        }
    },
    methods:{
        //关闭前的回调
        handleClose(){
            this.$emit('beforeclose','close')
        },
        //点击确定,关闭弹窗,通知父组件进行业务操作
        async clickDialog(){
            //先校验,然后校验通过通知父组件当前填写的数据信息,让父组件进行业务操作
            let flag = await this.$refs.dynamic.submitForm();
            if(flag){
                this.$emit('update:loading', true)
                let val = {...this.dialogForm.myForm}
                this.$emit('handleconfirm',val);
            }
        },
    }
}
</script>

然后我们看页面使用:

<template>
    <div class="pages-container">
        <el-button type="primary" @click="openDoor">打开带表单的弹窗</el-button>
        <form-dialog
            ref="dialogs"
            :title="dialogConfig.title"
            :visible.sync="dialogConfig.visible" 
            :width="dialogConfig.width"
            :dialogForm="dialogForm"
            :loading.sync="dialogConfig.loading"
            @handleconfirm="confirm"
            >
        </form-dialog>
    </div>
</template>

页面里我们发现多了一个dialogForm属性,这个是我们在使用的时候传递的表单数据。然后定义了一个ref,是为了找到我们表单的refs重置方法,来进行表单提交成功后的表单重置。
这里说到一个坑,我们再进行一次业务操作后,关闭弹窗,再次打开后,会遗留上次的填写数据,如果直接执行表单的this.$refs[formName].resetFields()方法,不能完全清空表单(自定义组件,比如自己封装的图片,select组件等)数据,而且会存在校验结果显示在下面。很讨厌。
这里我们要先手动清空表单的各个属性值,然后再调用resetFields(),这个方法是用来对该表单项进行重置,将其值重置为初始值并移除校验结果的,而不是用来清空的,这里要注意。

<script>
import FormDialog from '@/mycomponents/Dialog/form.vue'
//我们在dialogForm中定义好表单需要的配置数据
import {dialogForm} from './const.js'
//引入了一个清空表单的方法,对表单进行遍历,
//然后区分对象属性值中是普通string类型还是数组类型,清空成字符串和空数组
import {clearObject} from '@/utils/index.js'
export default {
    components:{FormDialog},
    data(){
        return {
            dialogForm:dialogForm,
            dialogConfig:{
                width:'800px',
                title:'表格弹窗标题',
                visible:false,
                loading:false,
            },//弹窗配置
        }
    },
    methods:{
        //打开表单弹窗
        openDoor(){
            this.dialogConfig.visible = true;
        },
        //弹窗点击确认按钮,获取数据成功提交给后台,关闭loading和弹窗,清空表单
        confirm(val){
            setTimeout(()=>{
                //关闭loading
                this.dialogConfig.loading = false;
                //关闭弹窗 在这之前取得val后发送给后台进行业务回调
                this.dialogConfig.visible = false;
                //找到我们表单组件的ref属性,然后作为参数提交给清空方法,执行重置表单API
                let ref = this.$refs.dialogs.$refs.dynamic;
                //封装的清空表单方法(//循环对象属性,重置各个属性值为空;)
                clearObject(this.dialogForm.myForm,this,ref).then();
                console.log(val);
            },3000)
        },
    }
}
</script>

我们看到上面提到一个清空对象属性值的方法,这里我写一下这段代码

//obj是我们要清空的表单object;
//_this就是我们页面的this,用它来做指向
//ref是我们要找的表单组件的ref,利用它来执行表单组件里面的重置方法
//$nextTick是等页面表单清空并渲染后再执行重置方法;
export function clearObject(obj,_this,ref){
   
    let data = {...obj}
    for (var key in data){
        if(data[key].isArray){
            data[key] = []
        }else{
            data[key] = ''
        }
    };
    _this.myForm = data;
    _this.$nextTick(()=>{
        ref.resetForm();
    })
    return Promise.resolve(data)
}

好了,到这里,我们的表单弹窗就封装好了。再来类似的页面,轻轻松松就写完,剩下的时间我们就可以悄悄的摸鱼了。
如果觉得对你有所帮助的话,点个赞吧,谢谢!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容