Vue3?函數(shù)式彈窗的實(shí)例小結(jié)
運(yùn)行環(huán)境
- vue3
- vite
- ts
- element-plus
開(kāi)發(fā)與測(cè)試
1. 使用h、render函數(shù)創(chuàng)建Dialog
- 建議可在plugins目錄下創(chuàng)建dialog文件夾,創(chuàng)建index.ts文件,代碼如下
import { h, render } from "vue";
/**
* 函數(shù)式彈窗
* @param component 組件
* @param options 組件參數(shù)
* @returns
*/
function createDialog(component: any, options: any) {
return new Promise((resolve, reject) => {
// 創(chuàng)建一個(gè)div節(jié)點(diǎn)
const mountNode = document.createElement("div");
// 將div節(jié)點(diǎn)拼接到Dom的body節(jié)點(diǎn)下
document.body.appendChild(mountNode);
// 使用h函數(shù)創(chuàng)建節(jié)點(diǎn)
const vNode = h(component, {
...options,
// 注意: vue子組件emit回調(diào)事件名稱(chēng)必須以on開(kāi)頭
onSubmit: data => {
resolve(data);
// 移除節(jié)點(diǎn)
document.body.removeChild(mountNode);
},
onCancel: data => {
reject(data);
// 移除節(jié)點(diǎn)
document.body.removeChild(mountNode);
}
});
// 渲染Dialog
render(vNode, mountNode);
});
}
export default createDialog;2. 全局掛載函數(shù)式彈窗
在main.ts中引入彈窗,并掛載在app上
// 引入函數(shù)式彈窗 import Dialog from "@/plugins/dialog"; const app = createApp(App); // 掛載到app app.config.globalProperties.$dialog = Dialog;
3. 測(cè)試
3.1 創(chuàng)建一個(gè)彈窗組件 testDialog.vue
<template>
<el-dialog v-model="dialogVisible" title="測(cè)試函數(shù)式彈窗" width="50%">
<span>{{ props.content }}</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCancel">Cancel</el-button>
<el-button type="primary" @click="handleSubmit"> Submit </el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { reactive, toRefs } from "vue";
// 注意: 需要按需引入使用到的第三方UI組件
import { ElDialog, ElButton } from "element-plus";
const props = withDefaults(
defineProps<{
show?: boolean; // moadl開(kāi)關(guān)
content?: string; // 內(nèi)容
}>(),
{}
);
const emits = defineEmits(["submit", "cancel"]);
const state = reactive({
dialogVisible: props.show
});
const { dialogVisible } = toRefs(state);
/** submit */
const handleSubmit = () => {
// 回調(diào)
emits("submit", { action: "submit", msg: "submit back" });
// 關(guān)閉彈窗
dialogVisible.value = false;
};
/** cancel */
const handleCancel = () => {
// 回調(diào)
emits("cancel", { action: "cancel", msg: "cancel back" });
// 關(guān)閉彈窗
dialogVisible.value = false;
};
</script>3.2 函數(shù)式調(diào)用彈窗
<template>
<!-- 動(dòng)態(tài)函數(shù)式彈窗 -->
<div class="test_dialog">
<el-button @click="openModal">調(diào)用函數(shù)式彈窗</el-button>
</div>
</template>
<script lang="ts" setup>
import { getCurrentInstance } from "vue";
import TestDialog from "./testDialog.vue";
// 通過(guò)全局的上下文拿到 proxy 屬性
const { proxy } = getCurrentInstance();
// 調(diào)用函數(shù)式彈窗
const openModal = () => {
// 調(diào)用彈窗
proxy
.$dialog(TestDialog, {
show: true,
content: "調(diào)用彈窗成功了!"
})
.then(res => {
// submit
console.log(res);
})
.catch(error => {
// cancel 回調(diào)
console.log(error);
});
};
</script>
<style lang="scss" scoped>
.test_dialog {
padding: 50px;
}
</style>3.3 測(cè)試效果

問(wèn)題
非原生的html元素?zé)o法渲染,如elements-plus組件無(wú)法在彈窗渲染
因?yàn)槭褂胔函數(shù)無(wú)法渲染第三方UI,需要在彈窗中單獨(dú)引入,如上面測(cè)試代碼使用的element-plus的modal和button都需要按需引入一次。如果沒(méi)有引入彈窗都不會(huì)show出來(lái),控制臺(tái)會(huì)給于警告如下截圖,通過(guò)這個(gè)截圖也可以看到,h函數(shù)是幫我們將彈窗組件拼接到了DOM中,組件的參數(shù)一并拼接了進(jìn)去,與傳統(tǒng)的調(diào)用方式近似。

在調(diào)用dialog的代碼中,ts會(huì)有代碼警告
可以全局申明下掛載的dialog,可直接在main.ts添加下面的申明
// 全局申明下$dialog,可以去除調(diào)用時(shí)ts的警告
declare module "vue" {
export interface ComponentCustomProperties {
$dialog: any;
}
}到此這篇關(guān)于Vue3 函數(shù)式彈窗的文章就介紹到這了,更多相關(guān)Vue3 函數(shù)式彈窗內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
簡(jiǎn)單說(shuō)說(shuō)如何使用vue-router插件的方法
這篇文章主要介紹了如何使用vue-router插件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
vue3.0?移動(dòng)端二次封裝van-uploader實(shí)現(xiàn)上傳圖片(vant組件庫(kù))
這篇文章主要介紹了vue3.0?移動(dòng)端二次封裝van-uploader上傳圖片組件,此功能最多上傳6張圖片,并可以實(shí)現(xiàn)本地預(yù)覽,實(shí)現(xiàn)代碼簡(jiǎn)單易懂,需要的朋友可以參考下2022-05-05
使用van-picker?動(dòng)態(tài)設(shè)置當(dāng)前選中項(xiàng)
這篇文章主要介紹了使用van-picker?動(dòng)態(tài)設(shè)置當(dāng)前選中項(xiàng)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
vue如何通過(guò)某個(gè)字段獲取詳細(xì)信息
這篇文章主要介紹了vue如何通過(guò)某個(gè)字段獲取詳細(xì)信息,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07

