這篇文章主要講解了“如何用Vue實(shí)現(xiàn)Dialog封裝”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“如何用Vue實(shí)現(xiàn)Dialog封裝”吧!
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供永安網(wǎng)站建設(shè)、永安做網(wǎng)站、永安網(wǎng)站設(shè)計(jì)、永安網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、永安企業(yè)網(wǎng)站模板建站服務(wù),10年永安做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
在寫業(yè)務(wù)的時(shí)候很常見的一個(gè)場(chǎng)景就是需要在不同的頁面調(diào)用同一個(gè)表單,常用的交互就是把表單以彈窗的形式展示,但是在每個(gè)頁面又重復(fù)的引入表單組件有時(shí)候又很麻煩

解決方案有兩個(gè):
在根組件里面引入動(dòng)態(tài)組件,在業(yè)務(wù)里面通過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 里面我個(gè)人感覺寫成插件是比較好用的,實(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)畫結(jié)束后銷毀實(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)打開,動(dòng)態(tài)了混入生命周期函數(shù)和銷毀操作
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 的升級(jí)Vue.extend沒有了,$mount也沒有了,組件只能在應(yīng)用里面去渲染
每個(gè)應(yīng)用之間的數(shù)據(jù)是隔離的,所以插件什么的都要重新引入。同時(shí)如果要交互交互的話也比較麻煩,引入同一個(gè) vuex 實(shí)例應(yīng)該可以,但是沒怎試
為了低耦合只能去新建一個(gè)應(yīng)用去掛載渲染

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)畫結(jié)束后銷毀實(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á)到了要求,但是完全是一個(gè)新引應(yīng)用了,如果在業(yè)務(wù)里訪問this.$root,vuex,router還是有點(diǎn)麻煩的
所以 Vue3 里面還是動(dòng)態(tài)組件的寫法比較好
在根組件引入動(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)用的的話this.$root.$dialog(),看起來太難看,其實(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)畫結(jié)束后銷毀實(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 || {})
})
}
}vue3 組件實(shí)例獲取應(yīng)用實(shí)例
vm.$.appContext.app == app
vue3 應(yīng)用實(shí)例獲取組件實(shí)例,注意_instance 僅在 dev 環(huán)境能訪問到
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實(shí)現(xiàn)Dialog封裝”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)如何用Vue實(shí)現(xiàn)Dialog封裝這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
當(dāng)前名稱:如何用Vue實(shí)現(xiàn)Dialog封裝
網(wǎng)站鏈接:http://www.chinadenli.net/article40/pecgho.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計(jì)公司、網(wǎng)站改版、網(wǎng)站收錄、網(wǎng)站制作、搜索引擎優(yōu)化、定制網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)