我是这样二次封装弹窗组件的

173 阅读1分钟

弹窗组件是我们工作中经常遇到的业务组件,特别是中后台的管理系统中十分常见,所以对它简单的封装下能起到事半功倍的效果,当然封装它的方法有很多种,下面我分享下我是如何基于element-ui和vue封装的。直接上代码:

弹窗组件 DialogComp.vue

<template>
    <el-dialog
      v-bind="$attrs"
      :title="dialogTitle"
      :width="dialogWidth"
      :visible.sync="isShowDialog"
      @close="cancel"
      v-else
      >
      <slot ></slot>
      <span slot="footer" class="dialog-footer">
        <el-button type="submit" :loading="saveLoading" @click="save" v-if="isShowSaveBtn">保 存</el-button>
        <el-button @click="cancel">取 消</el-button>
      </span>
    </el-dialog>
</template>
<script>
    export default {
      name:'DialogComp',
      model: { // 外部调用处可通过v-model的形式控制显示隐藏
        prop: 'dialogVisible',
        event: 'closeDialog'
      },
      props:{
        dialogVisible:{ //弹窗显示隐藏属性
          type:Boolean,
          default:false
        },
        dialogTitle:{
          type:String,
          required:true
        },
        dialogWidth:{
          type:String,
          default:'50%'
        },
        isShowSaveBtn:{ // 是否显示保存按钮
          type:Boolean,
          default:true
        },
        onConfirm:Function // 外部传入的保存提交方法
      },
      data(){
        return{
          saveLoading:false
        }
      },
      computed:{
        isShowDialog:{
          get(){
            return this.dialogVisible
          },
          set(){}
        }
      },
      methods:{
        cancel(){
          this.$emit('closeDialog',false)
        },
        /**
            组件内部通过定义saveLoading属性给保存按钮加一个点提交后按钮loading的效果,
            等保存接口调用完成loading效果再消失,注意这里外部传入的保存方法一定要是个异步方法,
            这样就不用在调用这个组件的地方每次都设置一个loading
        */
        save(){
          if(this.saveLoading)return
            this.saveLoading=true
            this.onConfirm().then(()=>{
              this.saveLoading=false
            })
        }
      }
    }
</script>

外部如何调用

<DialogComp
    :modal-append-to-body="true"
    :close-on-click-modal="false"
    append-to-body
    v-model="dialogVisible"
    :dialogTitle="title"
    :isShowSaveBtn="title!=='查看'"
    :onConfirm="handleConfirm"
    >
    <DynamicForm  :fieldList="fieldList" :isOnlyShow="title=='查看'" :defaultData="detailFormData" ref="dynamicFormRef" v-if="dialogVisible"/>
 </DialogComp>

传入的保存方法

//新增编辑保存
    async handleConfirm(){
      const isValidPass=await this.$refs.dynamicFormRef.validateForm()
      const formData=this.$refs.dynamicFormRef.getFormData()
      console.log('formData',formData)
      const params={
        ...formData,
        area:formData.county,
        areaCode:formData.countyCode
      }
      if(this.editId){
        params.id=this.editId
      }
      const askApi=this.editId ? update_department : create_department
      if(isValidPass){
        return new Promise((resolve,reject)=>{ // 包一层promise实现异步
          askApi(params).then(res=>{
            if(res.code==200){
              this.dialogVisible=false
              this.$message.success(this.editId ? '修改成功' : '新增成功')
              this.getTableData()

            }
          }).finally(()=>{
            resolve()
          })

        })
      }
    },

至此完结,感谢大家