Vue3使用 createApp 自定義通用Dialog的方法
最近在做一個項目的技術棧升級,從Vue2升級至Vue3,Vue2中有一個通用的全局 Dialog 方法,是通過 Vue.extend 來實現(xiàn)的,具體請看下方的Vue2代碼:
一、main.js 中定義通用方法
Vue.prototype.$dialog = {
open(component, args) {
return new Promise((resolve, reject) => {
let Dialog = Vue.extend(component);
var $vm = new Dialog({
el: document.createElement("div"),
router,
store,
eventBus: new Vue(),
});
var node = document.body.appendChild($vm.$el);
$vm.open(args).then(
result => {
if (resolve) {
resolve(result);
}
node.remove();
$vm.$destroy();
},
(arg) => {
if (reject) {
reject(arg)
}
node.remove();
$vm.$destroy();
}
);
});
}
};二、定義通用 DialogLayout.vue
<template>
<el-dialog :title="title" :visible.sync="visible" :center="center" :modal="true" :width="width"
class="n-dialog-layout" :class="$slots.footer ? 'has-footer' : ''" :modal-append-to-body="true"
:append-to-body="true" :lock-scroll="true" :show-close="showClose" :close-on-click-modal="false"
:before-close="beforeClose" @opened="$emit('opened')" @close="handleClose" :fullscreen="fullscreen">
<slot name="title" slot="title"></slot>
<slot></slot>
<slot name="footer" slot="footer"></slot>
</el-dialog>
</template>
<script>
export default {
name: "n-dialog-layout",
props: {
title: {},
fullscreen: {
default: false,
type: Boolean,
},
width: {
default: "50%",
type: String,
},
showClose: {
default: true,
type: Boolean,
},
center: {
default: false,
type: Boolean,
},
beforeClose: {
default: (done) => {
done();
},
type: Function,
},
},
data() {
return {
promise: null,
resolve: null,
reject: null,
visible: false,
confirmClose: false,
result: {},
};
},
methods: {
open() {
this.confirmClose = false;
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
this.visible = true;
});
return this.promise;
},
close(result) {
this.confirmClose = true;
this.result = result;
this.visible = false;
},
cancel(arg) {
this.confirmClose = false;
this.result = arg;
this.visible = false;
},
handleClose() {
if (this.confirmClose) {
this.resolve(this.result);
} else {
this.reject(this.result);
}
},
},
};
</script>三、 定義需要通過 Dialog 打開的具體頁面
<template>
<n-dialog-layout :title='l("ChangePassword")' ref="dialog">
<div class="info" v-loading="loading">
<el-form ref="passwordForm" status-icon size="large" :model="item" label-width="100px" label-position="top"
class="m-b" :rules="rules">
<el-form-item :label="l('CurrentPassword')" prop="currentPassword">
<el-input type="password" v-model="item.currentPassword"></el-input>
</el-form-item>
<el-form-item :label="l('NewPassword')" prop="password">
<el-input type="password" v-model="item.password"></el-input>
</el-form-item>
<el-form-item :label="l('NewPasswordRepeat')" prop="confirmPassword">
<el-input type="password" v-model="item.confirmPassword"></el-input>
</el-form-item>
</el-form>
</div>
<template slot="footer">
<span class="dialog-footer">
<el-button @click="cancel()" size="large">{{ l('Cancel') }}</el-button>
<el-button type="primary" @click="ok()" size="large">{{ l('Save') }}</el-button>
</span>
</template>
</n-dialog-layout>
</template>四、具體使用
import ChangePasswordDialog from './dialog/changePassword';
this.$dialog.open(ChangePasswordDialog).then(res => {
this.save();
})五、如何用 Vue3 的語法來重寫 main.js 中的 $dialog 方法?
- app.config.globalProperties 代替 Vue.prototype;
- 用什么來代替 Vue.extend 呢?這里使用的 createApp;
- createApp 代替 Vue.extend 以后遇到的問題,例如:無法使用 ElementPlus 的UI控件、無法解析全局注冊的組件
問題1:無法使用 ElementPlus 的UI控件、無法解析全局注冊的組件回答: 使用 createApp 創(chuàng)建出來的應用實例,use ElementPlus,register 里面是我放的全局通用方法和組件問題2:為什么Dialog.mount 的節(jié)點是寫死的?而不是 動態(tài) document.createElement ?回答:實踐過程中發(fā)現(xiàn) document.createElement 通過 proxy.$dialog.open(ChangePasswordDialog) 打開正常,但是加上 .then() 就會出現(xiàn)關閉兩次才可以正常關閉的情況
createdApp 代替 Vue.extend 實現(xiàn)創(chuàng)建一個“子類”,實現(xiàn)同樣的效果,先看代碼
app.config.globalProperties.$dialog = {
open(component, args) {
return new Promise((resolve, reject) => {
const Dialog = createApp(component);
Dialog.use(ElementPlus);
Dialog.use(register);
const $vm = Dialog.mount("#Dialog");
const node = document.body.appendChild($vm.$el);
$vm.open(args).then(
(result) => {
if (resolve) {
resolve(result);
}
node.remove();
},
(arg) => {
if (reject) {
reject(arg);
}
node.remove();
}
);
});
},
};具體效果如下
比較靈活,可插拔的通用Dialog

到此這篇關于Vue3 如何優(yōu)雅的使用 createApp 自定義通用Dialog的文章就介紹到這了,更多相關Vue3自定義通用Dialog內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
iview實現(xiàn)動態(tài)表單和自定義驗證時間段重疊
這篇文章主要介紹了iview實現(xiàn)動態(tài)表單和自定義驗證時間段重疊,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-01-01
elementUI給el-tabs/el-tab-pane添加圖標效果實例
這篇文章主要給大家介紹了關于elementUI給el-tabs/el-tab-pane添加圖標效果實例的相關資料,文中通過實例代碼介紹的非常詳細,對大家學習或者使用elementUI具有一定的參考學習價值,需要的朋友可以參考下2023-07-07
vue elementui select標簽監(jiān)聽change事件失效問題
這篇文章主要介紹了vue elementui select標簽監(jiān)聽change事件失效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04

