vue3動態(tài)加載對話框的方法實例
簡介
介紹使用vue3的異步組件動態(tài)管理對話框組件,簡化對話框組件使用方式。本文使用的是vue3、typescript、element_plus完成的示例。
常規(guī)方式使用對話框
一般情況下,使用對話框組件,會使用v-model進行雙向綁定,通過visible變量控制對話框的顯示和關閉。常規(guī)方式有一個弊端,自定義組件中使用<el-dialog>,需要通過父組件控制自定義組件是否展示。
<template> <ElButton type="primary" @click="openGeneral()">常規(guī)方式打開Modal</ElButton> <el-dialog v-model="dialogVisible" title="Tips" width="30%" :before-close="handleClose" > <span>This is a message</span> <template #footer> <span class="dialog-footer"> <el-button @click="dialogVisible = false">Cancel</el-button> <el-button type="primary" @click="dialogVisible = false" >Confirm</el-button > </span> </template> </el-dialog> </template>
<script setup lang="ts"> // This starter template is using Vue 3 <script setup> SFCs // Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup import {ref } from 'vue'; const dialogVisible = ref(false) const openGeneral=()=>{ dialogVisible.value=true } </script>
異步動態(tài)加載
先看使用異步組件進行動態(tài)加載對話框的方式。異步組件使用到的是defineAsyncComponent接口,只有使用到這個組件,才會從網(wǎng)絡上加載。動態(tài)操作使用的useDzModal
使用方式
<template> <ElButton type="primary" @click="openTestModalAsync()">動態(tài)異步打開TestModal</ElButton> </template>
<script setup lang="ts"> import { defineAsyncComponent,ref } from 'vue'; import { ElMessageBox } from 'element-plus'; import { useDzModal } from './dzmodal' // 異步加載組件 const TestModalAsync = defineAsyncComponent(()=>import('./components/TestModal.vue')) const dzmodal = useDzModal() // # 通過dzmodal動態(tài)操作對話框 const openTestModalAsync=()=>{ dzmodal.open(TestModalAsync,{ name:'張三' }) .then(res=>{ if(res.type==='ok'){ ElMessageBox.alert('TestModal點擊了確定'); }else{ ElMessageBox.alert('TestModal點擊了取消'); } }) } </script>
TestModal.vue
<script setup lang="ts"> import { reactive, ref, defineProps } from 'vue' const emits = defineEmits(['ok','cancel']) const props = defineProps({ name: String }); const dialogVisible = ref(true) const resultData= reactive({ type:'ok', data:{} }) </script> <template> <el-dialog v-model="dialogVisible" title="TestModal" width="30%" > <div>通過DzModal打開TestModal</div> <div>外部傳入:{{ name }}</div> <template #footer> <span class="dialog-footer"> <el-button @click="emits('cancel',{});dialogVisible = false">Cancel</el-button> <el-button type="primary" @click="emits('ok',{});dialogVisible = false" >Confirm</el-button > </span> </template> </el-dialog> </template> <style scoped> </style>
使用結(jié)果
動態(tài)操作對話框的實現(xiàn)
動態(tài)操作對話框,主要思路是動態(tài)創(chuàng)建虛擬dom節(jié)點,將對話框組件渲染到組件上,核心關鍵點是要動態(tài)創(chuàng)建的節(jié)點的上下文為當前app上下文vm.appContext = this._app._context
DzModalService.ts
import { App, inject, Plugin, h, render} from 'vue' import { ComponentOptions } from 'vue'; export const DzModalSymbol = Symbol() export class DzModalResult{ type: 'ok'|'cancel'|'string' = 'ok' body?:any= undefined } export class DzModalService{ private _app?:App=undefined constructor(app:App){ this._app=app; } public open(modal:ComponentOptions, props?: any):Promise<DzModalResult>{ return new Promise((reslove,reject)=>{ if(!this._app){ reject('_app is undefined') return; } const container = document.createElement("div"); document.body.appendChild(container) // 這里需要合并props,傳入到組件modal const vm = h(modal, { ...props, onOk:(data?:any)=>{ // 彈出框關閉時移除節(jié)點 document.body.removeChild(container) reslove(this.ok(data)); }, onCancel:(data?:any)=>{ reslove(this.cancel(data)); } }); // 這里很重要,關聯(lián)app上下文 vm.appContext = this._app._context render(vm,container); }); } public ok(data?:any):DzModalResult{ const result = new DzModalResult(); result.type='ok'; result.body=data; return result; } public cancel(data?:any):DzModalResult{ const result = new DzModalResult(); result.type='cancel'; result.body=data; return result; } } export function useDzModal(): DzModalService { const dzModal = inject<DzModalService>(DzModalSymbol) if(!dzModal){ throw new Error('No DzModal provided!') } return dzModal; } const plugin: Plugin = { install(app:App, options?:{[key:string]:any}){ const dzModal = new DzModalService(app) app.config.globalProperties.$dzModal= dzModal app.provide(DzModalSymbol, dzModal) } } export default plugin;
main.ts
import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import DzModal from './dzmodal' createApp(App) .use(ElementPlus) .use(DzModal) // 安裝 dzmodal插件 .mount('#app')
總結(jié)
使用異步動態(tài)加載對話框,父組件無需控制對話框組件的visible屬性 , 這樣可以簡化父組件操作,不在關心對話框組件在什么時間關閉,如果對話框組件需要訪問網(wǎng)絡,也在子組件中完成。父組件主要做兩件事:
- 通過異步組件方式引入對話框組件
- 打開對話框組件
到此這篇關于vue3動態(tài)加載對話框的文章就介紹到這了,更多相關vue3動態(tài)加載對話框內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Vue的route-view子頁面調(diào)用父頁面的函數(shù)詳解
這篇文章主要介紹了Vue的route-view子頁面調(diào)用父頁面的函數(shù)詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07vue.js表單驗證插件(vee-validate)的使用教程詳解
這篇文章主要介紹了vue.js表單驗證插件(vee-validate)的使用,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-05-05