色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Vue實(shí)現(xiàn)Dialog封裝

瀏覽:43日期:2022-09-28 11:56:38
目錄Vue2 寫(xiě)法Vue3 插件版寫(xiě)法Vue3 動(dòng)態(tài)組件寫(xiě)法一些比較 hack 的寫(xiě)法

在寫(xiě)業(yè)務(wù)的時(shí)候很常見(jiàn)的一個(gè)場(chǎng)景就是需要在不同的頁(yè)面調(diào)用同一個(gè)表單,常用的交互就是把表單以彈窗的形式展示,但是在每個(gè)頁(yè)面又重復(fù)的引入表單組件有時(shí)候又很麻煩

Vue實(shí)現(xiàn)Dialog封裝

解決方案有兩個(gè):

在根組件里面引入動(dòng)態(tài)組件,在業(yè)務(wù)里面通過(guò)this.$root.openDialog(name, props)去控制動(dòng)態(tài)組件的展示形式 封裝成插件的形式去調(diào)用,比如this.$dialog(’EditDialog.vue’, props)

當(dāng)然了,業(yè)務(wù) Dialog 組件要有一套規(guī)范,props 接收一個(gè) onOk、onCancel 回調(diào),data 里面定義一個(gè) visible 屬性

<template> <el-dialog :title='title' :visible.sync='visible' append-to-body> <!-- 業(yè)務(wù)代碼 --> </el-dialog></template><script>export default { props: [’onOk’, ’其他業(yè)務(wù)需要的屬性’], data() { return { visible: false } }}</script>Vue2 寫(xiě)法

在 Vue2 里面我個(gè)人感覺(jué)寫(xiě)成插件是比較好用的,實(shí)現(xiàn)如下,使用混入做了一些操作,和業(yè)務(wù)進(jìn)行解耦

有點(diǎn)不太好的地方是組件是動(dòng)態(tài)插入的,Vue devtools 要刷新下才能看到組件

const mixin = { mounted() { document.body.appendChild(this.$el) this.visible = true }, watch: { visible(value) { // 動(dòng)畫(huà)結(jié)束后銷(xiāo)毀實(shí)例 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) => { // 相對(duì)于該插件的位置,靜態(tài)編譯期間會(huì)檢查的 import(’../components/dialogs/’ + name).then(module => { const component = module.default const mixins = component.mixins || [] mixins.push(mixin) // 實(shí)現(xiàn)自動(dòng)打開(kāi),動(dòng)態(tài)了混入生命周期函數(shù)和銷(xiāo)毀操作 component.mixins = mixins return Vue.extend(component)}).then(Dialog => { const dialog = new Dialog({ propsData: props || {} }) dialog.$mount()}) } }}

調(diào)用方式如下,注意 onOk 回調(diào)的 this 指向,使用箭頭函數(shù)直接就避免了 😎

this.$dialog(’GroupEdit.vue’, { type: ’edit’, group: {}, onOk: () => { this.freshList() }})Vue3 插件版寫(xiě)法

很糟糕的是,由于 Vue3 的升級(jí)Vue.extend沒(méi)有了,$mount也沒(méi)有了,組件只能在應(yīng)用里面去渲染

每個(gè)應(yīng)用之間的數(shù)據(jù)是隔離的,所以插件什么的都要重新引入。同時(shí)如果要交互交互的話(huà)也比較麻煩,引入同一個(gè) vuex 實(shí)例應(yīng)該可以,但是沒(méi)怎試

為了低耦合只能去新建一個(gè)應(yīng)用去掛載渲染

Vue實(shí)現(xiàn)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) { // 動(dòng)畫(huà)結(jié)束后銷(xiāo)毀實(shí)例 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 動(dòng)態(tài)組件寫(xiě)法

在 Vue3 里面,插件版的寫(xiě)法同樣達(dá)到了要求,但是完全是一個(gè)新引應(yīng)用了,如果在業(yè)務(wù)里訪(fǎng)問(wèn)this.$root,vuex,router還是有點(diǎn)麻煩的

所以 Vue3 里面還是動(dòng)態(tài)組件的寫(xiě)法比較好

在根組件引入動(dòng)態(tài) component,定義一些控制變量

<template> <router-view></router-view> <component :is='currentDialog' v-bind='currentDialogProps' /></template><script>export default { data() { return { currentDialog: null, currentDialogProps: null } }}</script>

調(diào)用的的話(huà)this.$root.$dialog(),看起來(lái)太難看,其實(shí)還是可以手動(dòng)模擬插件的效果的

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) {// 動(dòng)畫(huà)結(jié)束后銷(xiāo)毀實(shí)例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 的寫(xiě)法

vue3 組件實(shí)例獲取應(yīng)用實(shí)例

vm.$.appContext.app == app

vue3 應(yīng)用實(shí)例獲取組件實(shí)例,注意_instance 僅在 dev 環(huán)境能訪(fǎng)問(wèn)到

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 } }}

到此這篇關(guān)于Vue實(shí)現(xiàn)Dialog封裝的文章就介紹到這了,更多相關(guān)Vue Dialog封裝內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Vue
相關(guān)文章:
主站蜘蛛池模板: 亚洲精品久久精品h成人 | 亚洲精品成人网久久久久久 | 欧美日韩视频精品一区二区 | 韩日三级视频 | 亚洲网址在线 | 日韩精品永久免费播放平台 | 久久女同互慰一区二区三区 | 视频二区在线 | 99视频在线观看高清 | 国产精品美女免费视频大全 | 国产成人高清一区二区私人 | 国产精品一区二区丝瓜 | 国内精品久久久久影院不卡 | 久久这里有精品视频 | 久久国产精品影院 | 欧美一级级毛片 | 日本 亚洲 欧美 | 91情侣高清精品国产 | 国产91九色刺激露脸对白 | 成人黄色免费网址 | 久久精品免费全国观看国产 | 国产精品久久精品 | 国产亚洲自拍一区 | 欧美一区=区三区 | a级免费| 欧美成人全部视频 | 国产午夜永久福利视频在线观看 | 欧美一级大片在线观看 | 99在线视频免费观看 | 91九九| 久揄揄鲁一二三四区高清在线 | 日韩经典欧美精品一区 | 小明日韩在线看看永久区域 | 97在线视频观看 | 亚洲天堂毛片 | 有码视频在线观看 | 亚洲专区欧美专区 | 成年免费观看 | 深夜爽爽爽gif福利免费 | 国产成人亚洲精品无广告 | 国产精品偷伦费观看 |