电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Vue實現Dialog封裝

瀏覽:48日期:2022-09-28 11:56:38
目錄Vue2 寫法Vue3 插件版寫法Vue3 動態組件寫法一些比較 hack 的寫法

在寫業務的時候很常見的一個場景就是需要在不同的頁面調用同一個表單,常用的交互就是把表單以彈窗的形式展示,但是在每個頁面又重復的引入表單組件有時候又很麻煩

Vue實現Dialog封裝

解決方案有兩個:

在根組件里面引入動態組件,在業務里面通過this.$root.openDialog(name, props)去控制動態組件的展示形式 封裝成插件的形式去調用,比如this.$dialog(’EditDialog.vue’, props)

當然了,業務 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 寫法

在 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 插件版寫法

很糟糕的是,由于 Vue3 的升級Vue.extend沒有了,$mount也沒有了,組件只能在應用里面去渲染

每個應用之間的數據是隔離的,所以插件什么的都要重新引入。同時如果要交互交互的話也比較麻煩,引入同一個 vuex 實例應該可以,但是沒怎試

為了低耦合只能去新建一個應用去掛載渲染

Vue實現Dialog封裝

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,定義一些控制變量

<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 || {}) }) }}一些比較 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封裝的文章就介紹到這了,更多相關Vue Dialog封裝內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Vue
相關文章:
主站蜘蛛池模板: UV固化机_UVLED光固化机_UV干燥机生产厂家-上海冠顶公司专业生产UV固化机设备 | 福建成考网-福建成人高考网 | 一点车讯-汽车网站,每天一点最新车讯!| 合肥花魁情感婚姻咨询中心_挽回爱情_修复婚姻_恋爱指南 | 深圳南财多媒体有限公司介绍| 楼承板-钢筋楼承板-闭口楼承板-无锡优贝斯楼承板厂 | 日本SMC气缸接头-速度控制阀-日本三菱伺服电机-苏州禾力自动化科技有限公司 | 济南展厅设计施工_数字化展厅策划设计施工公司_山东锐尚文化传播有限公司 | 高低温试验箱-模拟高低温试验箱订制-北京普桑达仪器科技有限公司【官网】 | 济南网站建设_济南网站制作_济南网站设计_济南网站建设公司_富库网络旗下模易宝_模板建站 | 「安徽双凯」自动售货机-无人售货机-成人用品-自动饮料食品零食售货机 | 工业洗衣机_工业洗涤设备_上海力净工业洗衣机厂家-洗涤设备首页 bkzzy在职研究生网 - 在职研究生招生信息咨询平台 | KBX-220倾斜开关|KBW-220P/L跑偏开关|拉绳开关|DHJY-I隔爆打滑开关|溜槽堵塞开关|欠速开关|声光报警器-山东卓信有限公司 | 本安接线盒-本安电路用接线盒-本安分线盒-矿用电话接线盒-JHH生产厂家-宁波龙亿电子科技有限公司 | 哈希余氯测定仪,分光光度计,ph在线监测仪,浊度测定仪,试剂-上海京灿精密机械有限公司 | 东莞螺杆空压机_永磁变频空压机_节能空压机_空压机工厂批发_深圳螺杆空压机_广州螺杆空压机_东莞空压机_空压机批发_东莞空压机工厂批发_东莞市文颖设备科技有限公司 | 济南网站建设|济南建网站|济南网站建设公司【济南腾飞网络】【荐】 | 铝合金重力铸造_铝合金翻砂铸造_铝铸件厂家-东莞市铝得旺五金制品有限公司 | 3D全息投影_地面互动投影_360度立体投影_水幕灯光秀 | 广东银虎 蜂窝块状沸石分子筛-吸附脱硫分子筛-萍乡市捷龙环保科技有限公司 | 苏州工作服定做-工作服定制-工作服厂家网站-尺品服饰科技(苏州)有限公司 | 线粒体膜电位荧光探针-细胞膜-标记二抗-上海复申生物科技有限公司 | SOUNDWELL 编码器|电位器|旋转编码器|可调电位器|编码开关厂家-广东升威电子制品有限公司 | 压装机-卧式轴承轮轴数控伺服压装机厂家[铭泽机械] | 薄壁轴承-等截面薄壁轴承生产厂家-洛阳薄壁精密轴承有限公司 | 二次元影像仪|二次元测量仪|拉力机|全自动影像测量仪厂家_苏州牧象仪器 | 北京自然绿环境科技发展有限公司专业生产【洗车机_加油站洗车机-全自动洗车机】 | 流量卡中心-流量卡套餐查询系统_移动电信联通流量卡套餐大全 | 低压载波电能表-单相导轨式电能表-华邦电力科技股份有限公司-智能物联网综合管理平台 | 尚为传动-专业高精密蜗轮蜗杆,双导程蜗轮蜗杆,蜗轮蜗杆减速机,蜗杆减速机生产厂家 | 武汉EPS线条_EPS装饰线条_EPS构件_湖北博欧EPS线条厂家 | 赛默飞Thermo veritiproPCR仪|ProFlex3 x 32PCR系统|Countess3细胞计数仪|371|3111二氧化碳培养箱|Mirco17R|Mirco21R离心机|仟诺生物 | 杭州实验室尾气处理_实验台_实验室家具_杭州秋叶实验设备有限公司 | 气动绞车,山东气动绞车,气动绞车厂家-烟台博海石油机械有限公司 气动隔膜泵厂家-温州永嘉定远泵阀有限公司 | 复合土工膜厂家|hdpe防渗土工膜|复合防渗土工布|玻璃纤维|双向塑料土工格栅-安徽路建新材料有限公司 | led冷热冲击试验箱_LED高低温冲击试验箱_老化试验箱-爱佩百科 | 冷藏车厂家|冷藏车价格|小型冷藏车|散装饲料车厂家|程力专用汽车股份有限公司销售十二分公司 | 纸布|钩编布|钩针布|纸草布-莱州佳源工艺纸布厂 | Copeland/谷轮压缩机,谷轮半封闭压缩机,谷轮涡旋压缩机,型号规格,技术参数,尺寸图片,价格经销商 CTP磁天平|小电容测量仪|阴阳极极化_双液系沸点测定仪|dsj电渗实验装置-南京桑力电子设备厂 | 山东聚盛新型材料有限公司-纳米防腐隔热彩铝板和纳米防腐隔热板以及钛锡板、PVDF氟膜板供应商 | 水厂自动化|污水处理中控系统|水利信息化|智慧水务|智慧农业-山东德艾自动化科技有限公司 | 东莞动力锂电池保护板_BMS智能软件保护板_锂电池主动均衡保护板-东莞市倡芯电子科技有限公司 |