您现在的位置是:主页 > Web前端技术 > Web前端技术

vue+el-element中根据文件名动态创建dialog的方法是什么开发技术

IDCBT2021-12-27服务器技术人已围观

简介这篇文章给大家介绍vue+el-element中根据文件名动态创建dialog的方法是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。 背景 在项目中使用对话框的通常做

这篇文章给大家介绍vue+el-element中根据文件名动态创建dialog的方法是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

背景

在项目中使用对话框的通常做法是把对话框封装成组件,在使用的地方引入,然后添加到template,使用visible.sync控制对话框的显示/隐藏,监听confirm事件处理用户点击确定。如下:

 <confirm-dialog
     v-if="confirmDialogVisible"
     :title="$t(`mineData.tips.deleteDataset`)"
     :visible.sync="confirmDialogVisible"
     @confirm="confimHandler"
 ></confirm-dialog>

 在封装的dialog内部也需要在关闭时更新visible,确定时触发confirm事件:

 methods: {
    close() {
        this.$emit("update:visible", false);
    },
    confirm() {
        this.close();
        this.$emit("confirm");
    }
}

这样的做法不仅仅导致页面初始化时引入所有对话框组件而影响加载速度,更头疼的是页面中引入了很多对话框时,会导致页面很杂乱:需要为每个对话框插入一段html,为每个对话框维护一个单独的visible变量,为每个对话框添加confirm事件监听...

而这些操作大部分是和业务无关的,且这些操作又是极其相似的。

那么,有没有通过js动态创建dialog的方法呢?

createDialog("confirm-dialog.vue");

就像上面这样根据文件名即可打开对话框,不用定义visible及添加一堆html和事件回调,甚至不需要先引入对话框组件!

是不是很简单!心动了吧?看下去吧。

实现
1.封装的/utils/dialogControl.js
import Vue from 'vue'
async function createDialog (fileName, data) {
  const dialogsContext = require.context(
    '../components', // 定义查找文件的范围
    true,
    /([a-zA-Z\-0-9]+)\.vue$/, // 定义文件名规则
    'lazy'
  )
  // 查找到传入名字的文件并加载该文件
  let match = dialogsContext.keys().find((key) => key.includes(fileName))
  if (!match) return
  let componentContext = await dialogsContext(match)
  let temp = componentContext.default
  return new Promise(function (resolve, reject) {
    // 初始化配置参数
    let opt = {
      data
    }
    let component = Object.assign({}, temp)
    let initData = {
      visible: true
    }
    Object.assign(initData, component.data())
    opt.data && Object.assign(initData, JSON.parse(JSON.stringify(opt.data)))
    component.data = function () {
      return initData
    }
    // 创建构造器创建实例挂载
    let DialogC = Vue.extend(component)
    let dialog = new DialogC()
    // 关闭事件
    let _onClose = dialog.$options.methods.onClose
    dialog.onClose = function () {
      resolve()
      dialog.$destroy()
      _onClose && _onClose.call(dialog)
      document.body.removeChild(dialog.$el)
    }
    // 回调事件
    let _onCallback = dialog.$options.methods.onCallback
    dialog.onCallback = function (...arg) {
      try {
        _onCallback && _onCallback()
        resolve(arg)
        dialog.$destroy()
        _onClose && _onClose.call(dialog)
        document.body.removeChild(dialog.$el)
      } catch (e) {
        console.log(e)
      }
    }
    dialog.$mount()
    // 点击关闭按钮时会改变visible
    dialog.$watch('visible', function (n, o) {
      dialog === false && dialog.onClose()
    })
    document.body.appendChild(dialog.$el)
  })
}

export { createDialog }

标签:

很赞哦! ()

本栏推荐