使用Vue.extend进行组件封装

因为业务需要封装一个拒绝审核并选择原因的的确认框,用普通的el-dialog是可以实现的,但是使用起来比较繁琐,需要定义一些中间变量以及回调函数等。 现在想比较优雅使用这个确认框,类似:

this.$prompt('请输入邮箱').then(confirm => {
	// some code
})

于是决定自己封装一个,首先去element-ui git仓库查看实现源码(点击跳转),了解实现原理,然后是马不停蹄的进行实践。 首先定义一个普通的vue组件:

// confirm.vue
<template>
  <el-dialog title="请选择拒绝原因" :visible="isShow" :before-close="() => close(true)" width="500px" :close-on-click-modal="false">
    <el-form :model="formdata" ref="form" label-width="100px">
      <el-form-item label="拒绝原因" prop="selectReason" :rules="[{ required: true, message: '拒绝原因不能为空', trigger: 'blur'}]">
        <el-select v-model="formdata.selectReason" placeholder="请选择原因" :loading="loading">
          <el-option v-for="item in list" :key="item.id" :value="item.template" :label="item.template"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="() => close()">确定</el-button>
        <el-button type="info" plain @click="() => close(true)">取消</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>
<script>
import { getList } from '@/api'
export default {
  name: 'ApplyConfirm',
  props: {
    isShow: Boolean
  },
  watch: {
    'isShow': function(val) {
      if (val) {
        this.loading = true
        getList().then(res => {
          this.list = res
        }).finally(() => {
          this.loading = false
        })
      } else {
        this.loading = false
        this.formdata.selectReason = ''
        this.$refs.form.clearValidate()
      }
    }
  },
  methods: {
    close(cancel = false) {
      if (this.callback && typeof this.callback === 'function') {
        if (!cancel) {
          this.$refs.form.validate(valid => {
            if (valid) {
              this.callback(cancel, this.formdata.selectReason)
            }
          })
        } else {
          this.callback(cancel)
        }
      }
    }
  },
  data() {
    return {
      callback: null,
      list: [],
      loading: false,
      formdata: {
        selectReason: ''
      }
    }
  }
}
</script>

然后定义一个js文件,来操控上面那个组件,使用到了Vue.extend (查看文档),我也是第一次使用,可能写的不太好见谅。

// confirm.js
import ApplyConfirm from './confirm.vue'
import Vue from 'vue'

const ApplyConfirmConstructor = Vue.extend(ApplyConfirm)

const instance = new ApplyConfirmConstructor({
  el: document.createElement('div')
})

document.body.appendChild(instance.$el);

export function ApplyConfirmBox() {
  return new Promise((resolve, reject) => {
    instance.callback = function(cancel, data = '') {
      if (!cancel) {
        resolve(data)
      } else {
        reject('取消')
      }
      instance.isShow = false
    }
    instance.isShow = true
  })
}

在页面里或者其他组件里直接调用即可,使用方式如下:

// 局部使用首先引入组件,全局使用可以在Vue.prototype上添加
import { ApplyConfirmBox } from '@/components/confirm/confirm.js'
// 调用
ApplyConfirmBox().then(res => {
        // some code
        // res是弹窗选择的内容
      }).catch(err => {
      	console.log(err) // 取消
      })

弹窗效果 微信图片_20221125094603


使用Vue.extend进行组件封装
https://blog.jishu6.com:18080//archives/selec-confirm
作者
tab
发布于
2022年11月25日
许可协议