用vue怎样实现dialog封装?方法是啥?
Admin 2021-09-09 群英技术资讯 846 次浏览
今天给大家分享的是关于vue实现dialog封装的内容,小编觉得挺实用的,因此分享给大家做个参考,下文还介绍了Vue2 写法、Vue3 插件版写法和Vue3 动态组件写法等等,感兴趣的朋友就继续往下看吧。
在写业务的时候很常见的一个场景就是需要在不同的页面调用同一个表单,常用的交互就是把表单以弹窗的形式展示,但是在每个页面又重复的引入表单组件有时候又很麻烦
解决方案有两个:
当然了,业务 Dialog 组件要有一套规范,props 接收一个 onOk、onCancel 回调,data 里面定义一个 visible 属性
<template> <el-dialog :title="title" :visible.sync="visible" append-to-body> <!-- 业务代码 --> </el-dialog> </template> <script> export default { props: ['onOk', '其他业务需要的属性'], data() { return { visible: false } } } </script>
在 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.parentNode) { this.$el.parentNode.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 的升级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 里面,插件版的写法同样达到了要求,但是完全是一个新引应用了,如果在业务里访问this.$root,vuex,router还是有点麻烦的
所以 Vue3 里面还是动态组件的写法比较好
在根组件引入动态 component,定义一些控制变量
<template> <router-view></router-view> <component :is="currentDialog" v-bind="currentDialogProps" /> </template> <script> export default { data() { return { currentDialog: null, currentDialogProps: null } } } </script>
调用的的话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 || {}) }) } }
vue3 组件实例获取应用实例
vm.$.appContext.app == app
vue3 应用实例获取组件实例,注意_instance 仅在 dev 环境能访问到
app._instance.proxy == vm app._instance.root.proxy == vm app._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封装就介绍到这,上述实例具有一定的借鉴价值,感兴趣的朋友可以参考学习,希望能对大家有帮助,想要了解更多大家可以关注群英网络其它相关文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要给大家分享vue实现全屏和退出全屏的内容,实现效果如下, vue中默认进来页面的某个div全屏,当退出全屏次数5次,那么就跳转其他页面,这一效果可以应用在线上答题考试中,下面我们就来具体看看怎样做吧。
本文实例为大家分享了vue引入Excel表格插件的具体代码,供大家参考,具体内容如下
前端开发人员只要了解过vue.js框架可能都知道单文件组件。vue.js中的单文件组件允许在一个文件中定义一个组件的所有内容。这是一个非常有用的解决方案,在浏览器网页中已经开始提倡这种机制。
这篇文章主要介绍了JavaScript数据结构与算法,文章围绕主题展开数据结构与算法的概念,以及几种常见的数据结构是什么,有什么优点和缺,具有一定的参考价值,需要的小伙伴可以参考一下
本篇文章给大家带来了关于JavaScript的相关知识,其中主要为大家介绍了JS Generator函数yield表达式示例详解,Generator函数是ES6提供的一种异步编程解决方案,下面一起来看一下,希望对大家有帮助。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008