千家信息网

Vue如何实现Dialog封装

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容主要讲解"Vue如何实现Dialog封装",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Vue如何实现Dialog封装"吧!在写业务的时候很常见的一
千家信息网最后更新 2026年11月03日Vue如何实现Dialog封装

本篇内容主要讲解"Vue如何实现Dialog封装",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Vue如何实现Dialog封装"吧!

在写业务的时候很常见的一个场景就是需要在不同的页面调用同一个表单,常用的交互就是把表单以弹窗的形式展示,但是在每个页面又重复的引入表单组件有时候又很麻烦

解决方案有两个:

  1. 在根组件里面引入动态组件,在业务里面通过this.$root.openDialog(name, props)去控制动态组件的展示形式

  2. 封装成插件的形式去调用,比如this.$dialog("EditDialog.vue", props)

当然了,业务 Dialog 组件要有一套规范,props 接收一个 onOk、onCancel 回调,data 里面定义一个 visible 属性

Vue2 写法

在 Vue2 里面我个人感觉写成插件是比较好用的,实现如下,使用混入做了一些操作,和业务进行解耦

有点不太好的地方是组件是动态插入的,Vue devtools 要刷新下才能看到组件

const mixin = {  mounted() {    document.body.appendChild(this.$el)    this.visible = true  },  watch: {    visible(value) {      // 动画结束后销毁实例      if (value === false) {        setTimeout(() => {          this.$destroy()          if (this.$el && this.$el[xss_clean]) {            this.$el[xss_clean].removeChild(this.$el)          }        }, 400)      }    }  }}export default {  install(Vue, options) {    Vue.prototype.$dialog = (name, props) => {      // 相对于该插件的位置,静态编译期间会检查的      import("../components/dialogs/" + name)        .then(module => {          const component = module.default          const mixins = component.mixins || []          mixins.push(mixin) // 实现自动打开,动态了混入生命周期函数和销毁操作          component.mixins = mixins          return Vue.extend(component)        })        .then(Dialog => {          const dialog = new Dialog({            propsData: props || {}          })          dialog.$mount()        })    }  }}

调用方式如下,注意 onOk 回调的 this 指向,使用箭头函数直接就避免了 ?

this.$dialog("GroupEdit.vue", {  type: "edit",  group: {},  onOk: () => {    this.freshList()  }})

Vue3 插件版写法

很糟糕的是,由于 Vue3 的升级Vue.extend没有了,$mount也没有了,组件只能在应用里面去渲染

每个应用之间的数据是隔离的,所以插件什么的都要重新引入。同时如果要交互交互的话也比较麻烦,引入同一个 vuex 实例应该可以,但是没怎试

为了低耦合只能去新建一个应用去挂载渲染

import { createApp, defineComponent } from "vue"import ElementPlus from "element-plus"const mixin = {  mounted() {    document.body.appendChild(this.$el)    this.visible = true  },  watch: {    visible(value) {      // 动画结束后销毁实例      if (value === false) {        setTimeout(() => {          this.$.appContext.app.unmount()        }, 400)      }    }  }}export default {  install(app) {    app.config.globalProperties.$dialog = (name, props) => {      import("../components/dialogs/" + name)        .then(module => {          const component = module.default          let mixins = component.mixins || []          mixins.push(mixin)          component.mixins = mixins          return defineComponent(component)        })        .then(Dialog => {          const app = createApp(Dialog, props || {})          app.use(ElementPlus)          app.mount(document.createElement("div"))        })    }  }}

Vue3 动态组件写法

在 Vue3 里面,插件版的写法同样达到了要求,但是完全是一个新引应用了,如果在业务里访问this.$root,vuex,router还是有点麻烦的

所以 Vue3 里面还是动态组件的写法比较好

在根组件引入动态 component,定义一些控制变量

调用的的话this.$root.$dialog(),看起来太难看,其实还是可以手动模拟插件的效果的

const app = createApp(App)const vm = app.mount("#app")initDialog(app, vm)function initDialog(app, vm) {  const mixin = {    mounted() {      this.visible = true    },    watch: {      visible(value) {        // 动画结束后销毁实例        if (value === false) {          setTimeout(() => {            this.$root.currentDialog = null            this.$root.currentDialogProps = {}          }, 400)        }      }    }  }  app.config.globalProperties.$dialog = (name, props) => {    import("./components/dialogs/" + name).then(module => {      const component = module.default      let mixins = component.mixins || []      mixins.push(mixin)      component.mixins = mixins      // 不需要 defineComponent(component)      vm.currentDialog = markRaw(component)      vm.currentDialogProps = markRaw(props || {})    })  }}

一些比较 hack 的写法

vue3 组件实例获取应用实例

vm.$.appContext.app == app

vue3 应用实例获取组件实例,注意_instance 仅在 dev 环境能访问到

app._instance.proxy == vmapp._instance.root.proxy == vmapp._instance.ctx.$root == vm

骚操作还是有的,但是最好不要用

const app = createApp(App)const vm = app.mount("#app")if (process.env.NODE_ENV === "production") {  app._instance = {    proxy: vm,    root: {      proxy: vm    },    ctx: {      $root: vm    }  }}

到此,相信大家对"Vue如何实现Dialog封装"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

组件 实例 动态 插件 业务 写法 应用 封装 还是 动画 形式 表单 麻烦 内容 函数 就是 属性 页面 学习 控制 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海挚品互联网科技有限公司 互联网科技图片 云信互联网科技有限公司 疫情对互联网科技公司影响 互联网 科技公司 互联网金融 科技金融 天津摩尔互联网科技 互联网高科技股票 互联网对科技的发展 华夏恒生互联网科技013171 产业互联网科技服务公司 互联网领先科技宣传片 从那以后互联网科技有限公司 广州有谷有贝互联网科技有限公司 互联网科技机房 万物互联网智能科技 科技互联网专业工作会议发言稿 重庆科技产业互联网有哪些 广东猫王互联网科技有限公司电话 株洲百竞科技的互联网营销顾问 百单网互联网科技有限公司 互联网新科技 互联网科技上市公司 沃里互联网科技 科技与互联网哪个更好 山东大美朱楼互联网科技有限公司 珠海东科互联网科技有限公司 美国五大互联网科技公司市值多少 重庆科技产业互联网有哪些 上海旺乐尼互联网科技有限公司
0