vue+el-element中根據(jù)文件名動態(tài)創(chuàng)建dialog的方法實踐
背景
在項目中使用對話框的通常做法是把對話框封裝成組件,在使用的地方引入,然后添加到template,使用visible.sync控制對話框的顯示/隱藏,監(jiān)聽confirm事件處理用戶點擊確定。如下:
<confirm-dialog
v-if="confirmDialogVisible"
:title="$t(`mineData.tips.deleteDataset`)"
:visible.sync="confirmDialogVisible"
@confirm="confimHandler"
></confirm-dialog>
?在封裝的dialog內(nèi)部也需要在關(guān)閉時更新visible,確定時觸發(fā)confirm事件:
methods: {
close() {
this.$emit("update:visible", false);
},
confirm() {
this.close();
this.$emit("confirm");
}
}
這樣的做法不僅僅導(dǎo)致頁面初始化時引入所有對話框組件而影響加載速度,更頭疼的是頁面中引入了很多對話框時,會導(dǎo)致頁面很雜亂:需要為每個對話框插入一段html,為每個對話框維護一個單獨的visible變量,為每個對話框添加confirm事件監(jiān)聽...
而這些操作大部分是和業(yè)務(wù)無關(guān)的,且這些操作又是極其相似的。
那么,有沒有通過js動態(tài)創(chuàng)建dialog的方法呢?
createDialog("confirm-dialog.vue");
就像上面這樣根據(jù)文件名即可打開對話框,不用定義visible及添加一堆html和事件回調(diào),甚至不需要先引入對話框組件!
是不是很簡單!心動了吧?看下去吧。
實現(xiàn)
1.封裝的/utils/dialogControl.js
import Vue from 'vue'
async function createDialog (fileName, data) {
const dialogsContext = require.context(
'../components', // 定義查找文件的范圍
true,
/([a-zA-Z\-0-9]+)\.vue$/, // 定義文件名規(guī)則
'lazy'
)
// 查找到傳入名字的文件并加載該文件
let match = dialogsContext.keys().find((key) => key.includes(fileName))
if (!match) return
let componentContext = await dialogsContext(match)
let temp = componentContext.default
return new Promise(function (resolve, reject) {
// 初始化配置參數(shù)
let opt = {
data
}
let component = Object.assign({}, temp)
let initData = {
visible: true
}
Object.assign(initData, component.data())
opt.data && Object.assign(initData, JSON.parse(JSON.stringify(opt.data)))
component.data = function () {
return initData
}
// 創(chuàng)建構(gòu)造器創(chuàng)建實例掛載
let DialogC = Vue.extend(component)
let dialog = new DialogC()
// 關(guān)閉事件
let _onClose = dialog.$options.methods.onClose
dialog.onClose = function () {
resolve()
dialog.$destroy()
_onClose && _onClose.call(dialog)
document.body.removeChild(dialog.$el)
}
// 回調(diào)事件
let _onCallback = dialog.$options.methods.onCallback
dialog.onCallback = function (...arg) {
try {
_onCallback && _onCallback()
resolve(arg)
dialog.$destroy()
_onClose && _onClose.call(dialog)
document.body.removeChild(dialog.$el)
} catch (e) {
console.log(e)
}
}
dialog.$mount()
// 點擊關(guān)閉按鈕時會改變visible
dialog.$watch('visible', function (n, o) {
dialog === false && dialog.onClose()
})
document.body.appendChild(dialog.$el)
})
}
export { createDialog }
說明:
1.需要指定查找文件的路徑及匹配名稱的正則表達式,這樣能過濾掉一些不需要的文件
2.接收一個fileName參數(shù)用于匹配要打開的對話框文件,data參數(shù)是傳遞給對話框的數(shù)據(jù),會合并到組件的data中
3.使用visible變量控制對話框的顯示/隱藏
4.定義了一個onClose方法用于關(guān)閉對話框,對話框中可以使用該方法進行關(guān)閉
5.onCallback方法用于向調(diào)用對話框的父組件傳值,如點擊確定按鈕時向父組件傳值
2.dialog文件定義
如/components/ConfirmDialog.vue,使用visible變量控制顯示/隱藏,onClose處理關(guān)閉事件,確定按鈕的回調(diào)是onCallback(和dialogControl.js中的定義一致)。
<template>
<el-dialog title="提示" :visible.sync="visible" width="30%">
<span>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nesciunt quis
perspiciatis fugiat molestiae provident accusantium repudiandae fugit
minima, eaque, repellat quibusdam iste sed ad? Debitis qui praesentium
minus incidunt esse!</span>
<span slot="footer" class="dialog-footer">
<el-button @click="onClose">取 消</el-button>
<el-button type="primary" @click="onCallback(true)">確 定</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
data () {
return {}
},
methods: {
}}
</script>
?3.使用
?引入dialogControl中的createDialog方法,直接傳入文件名稱即可打開。
如果有其他的屬性,則以鍵值對的形式放入第二個參數(shù),這些屬性會合并到對話框組件的data中,因此對話框組件中可以直接使用這些屬性。
createDialog方法得到一個promise對象,其then方法能得到confirm返回的結(jié)果。
<template>
<div>
<h1>This is an show page</h1>
<el-button type="primary" @click="openDialog">打開</el-button>
</div>
</template>
<script>
import { createDialog } from "@/utils/dialogControl";
export default {
methods: {
openDialog() {
let dialog = createDialog("confirm-dialog.vue");
dialog.then((v) => {
if (v) {
console.info("確定");
}
});
},
},
};
</script>
效果如下:
?
如果你還在使用文章開始的方式調(diào)用對話框,那么趕緊把這個方法用起來吧!?
參考:
https://www.freesion.com/article/43311065748/
到此這篇關(guān)于vue+el-element中根據(jù)文件名動態(tài)創(chuàng)建dialog的方法實踐的文章就介紹到這了,更多相關(guān)el-element 動態(tài)創(chuàng)建dialog內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決uniapp項目在微信開發(fā)工具里打開報錯Error:app.json:在項目根目錄未找到app.json
這篇文章主要給大家介紹了關(guān)于解決uniapp項目在微信開發(fā)工具里打開報錯Error:app.json:在項目根目錄未找到app.json的相關(guān)資料,文中通過圖文將解決的辦法介紹的非常詳細,需要的朋友可以參考下2024-03-03
vue+elementui實現(xiàn)點擊table中的單元格觸發(fā)事件--彈框
這篇文章主要介紹了vue+elementui實現(xiàn)點擊table中的單元格觸發(fā)事件--彈框,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
關(guān)于vue中@click.native.prevent的說明
這篇文章主要介紹了關(guān)于vue中@click.native.prevent的說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
vue實現(xiàn)移動端彈出鍵盤功能(防止頁面fixed布局錯亂)
這篇文章主要介紹了vue?解決移動端彈出鍵盤導(dǎo)致頁面fixed布局錯亂的問題,通過實例代碼給大家分享解決方案,對vue?移動端彈出鍵盤相關(guān)知識感興趣的朋友一起看看吧2022-04-04
對Vue- 動態(tài)元素屬性及v-bind和v-model的區(qū)別詳解
今天小編就為大家分享一篇對Vue- 動態(tài)元素屬性及v-bind和v-model的區(qū)別詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08

