教你輕松解決Vue?Dialog彈窗詬病
摘要
相信用Vue框架多的老哥對(duì)彈窗的使用的問(wèn)題都有一些使用上的詬病,本輪主要闡述針對(duì)組件封裝不符合邏輯編寫(xiě),如何最小化封裝達(dá)成簡(jiǎn)化調(diào)用目的。
分析
常規(guī)的Vue前端UI組件如elment-ui、Iview、Ant Design Vue等UI組件庫(kù)針對(duì)模態(tài)窗的封裝基本都是套式的,MVVM大家基本都在提,從另外一個(gè)角度分析Dialog封裝在實(shí)際使用上,彈窗過(guò)多時(shí)漫天的變量如何解決,我們把temlplate中的內(nèi)容理解為表現(xiàn)層,script理解為邏輯層,雖然解決了數(shù)據(jù)的綁定問(wèn)題,但說(shuō)實(shí)在的,vue的邏輯層和表現(xiàn)層互相穿插使用還是相對(duì)存在一些問(wèn)題,也許你會(huì)提Vue也支持Jsx寫(xiě)法,安裝了插件也能實(shí)現(xiàn)React的寫(xiě)法和效果,此時(shí)我以模態(tài)窗的例子來(lái)說(shuō)明一些問(wèn)題
- elment-ui

- Iview

- Ant Design Vue
大家在實(shí)踐過(guò)程中,實(shí)現(xiàn)這樣一個(gè)簡(jiǎn)單操作,點(diǎn)擊明細(xì)->彈窗表單信息->確定調(diào)用數(shù)據(jù)保存接口 這個(gè)過(guò)程如一個(gè)業(yè)務(wù)處理中有很多的編輯彈窗,或者保存邏輯需要連貫性,還有區(qū)分會(huì)憑空使得一個(gè)處理變得很凌亂復(fù)雜。
可以看到一個(gè)彈窗,如果擴(kuò)展3個(gè)data變量,兩個(gè)方法。如果有10個(gè)彈窗,那么也變將會(huì)多出來(lái)310個(gè)屬性和210個(gè)方法。 我們針對(duì)彈窗的調(diào)用習(xí)慣更傾向于layer和react這種隨時(shí)取用的寫(xiě)法
那么問(wèn)題來(lái)了,vue雖然號(hào)稱支持jsx寫(xiě)法如下圖,但卻會(huì)失去擁有當(dāng)前頁(yè)面屬性方法共享的部分權(quán)力,本質(zhì)上來(lái)說(shuō),其實(shí)就是函數(shù)式組件乃至于后來(lái)都趨向的鉤子函數(shù)或者叫組合式,其本質(zhì)也就是上下文的共享。

優(yōu)化辦法
如果結(jié)合vue特點(diǎn),要合并屬性和方法,必然要封裝模態(tài)窗為組件,但顯示和確認(rèn),并不是一個(gè)鏈結(jié)構(gòu),由此就必須實(shí)現(xiàn)一個(gè)回調(diào),但回調(diào)這種寫(xiě)法,往往是要在組件中進(jìn)行一些約定,而且現(xiàn)在在Promise橫行外加aysnc await 去JQ時(shí)代鏈?zhǔn)秸勰?/strong>的前提下,簡(jiǎn)單來(lái)講,異步調(diào)用但采用同步寫(xiě)法。 如果把Promise比作 "線程" 那我們就需要一個(gè)調(diào)度,去控制在點(diǎn)擊 “確認(rèn)” 時(shí)結(jié)束。
- deferred對(duì)象就是jQuery的回調(diào)函數(shù)解決方案,$.Deferred 給我提供了思路,也就是把promise對(duì)象的reject和resolve開(kāi)放出來(lái)
function generateDeferredPromise() {
return (() => {
let resolve;
let reject;
let p = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return {
promise: p,
reject,
resolve
};
})();
}- 完整的模態(tài)窗封裝如下,可以看到我們?cè)趕how的時(shí)候返回了promise對(duì)象,在確認(rèn)的時(shí)候觸發(fā)了回調(diào)
<template>
<el-dialog
:title="title"
:visible.sync="drawer">
<slot />
<div slot="footer" class="dialog-footer">
<el-button @click="drawer = false">取 消</el-button>
<el-button type="primary" @click="saveData">確 定</el-button>
</div>
</el-dialog>
</template>
<script>
function generateDeferredPromise() {
return (() => {
let resolve;
let reject;
let p = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return {
promise: p,
reject,
resolve
};
})();
}
export default {
name:'modal',
props: {
title: {
type: String,
default: undefined,
},
handle:{
type:Function,
default:(res)=>{},
}
},
data() {
return {
drawer: false,
promise:null,
}
},
mounted() {
if(this.handle){
this.handle(this);
}
},
methods: {
show() {
this.drawer = true
this.promise=new generateDeferredPromise();
return this.promise.promise;
},
saveData(){
this.promise.resolve();
this.promise.promise.then(()=>{
this.drawer=false;
})
}
}
}
</script>
<style>
</style>- 調(diào)用時(shí)如下,可以很輕松的變相達(dá)成函數(shù)式編程的特點(diǎn),在調(diào)用時(shí)減去了2個(gè)屬性和一個(gè)方法,10個(gè)彈窗由原本的30+20個(gè)減少為20。
<modal title="審批/反饋" ref="modal">
<el-descriptions :model="audit" class="margin-top" :column="1" border>
<el-descriptions-item label="意見(jiàn)">
<el-radio-group v-model="audit.state">
<el-radio :label="true">通過(guò)</el-radio>
<el-radio :label="false">不通過(guò)</el-radio>
</el-radio-group>
</el-descriptions-item>
<el-descriptions-item label="內(nèi)容">
<el-input type="textarea" v-model="audit.comment"></el-input>
</el-descriptions-item>
</el-descriptions>
</modal>
async handleAudit(row) {
const { show } = this.$refs["modal"] || {};
show().then(async () => {
//保存邏輯處理
});
},總結(jié)
- 本質(zhì)其實(shí)本次分享頁(yè)并沒(méi)有很多新意,這種引用式的封裝,很多人也早都想到了,只不過(guò)感覺(jué)針對(duì)彈窗這塊的封裝,很多走了極端,要么就追求layer那種寫(xiě)法兼容習(xí)慣,要么干脆還是保留原樣,只做一些特殊處理,屬性還是原樣保留了。
- 至于回調(diào),我之前雖然用過(guò)一段,但還是覺(jué)得不慎習(xí)慣,因?yàn)榕既挥袀€(gè)共享彈窗存在確認(rèn)后邏輯不同的問(wèn)題給我造成了困擾,覺(jué)得寫(xiě)法有點(diǎn)兒變態(tài),因此做了一些嘗試和延展,覺(jué)得算是比較良性的一個(gè)調(diào)用方式吧。
- 框架性的東西,我詫異的是,理論性的東西,一個(gè)比一個(gè)探的深,但涉及到便捷性,卻很少有人去探究,乃至于框架性的東西除了UI和風(fēng)格不同,寫(xiě)法也大同小異。
到此這篇關(guān)于輕松解決Vue Dialog彈窗詬病的文章就介紹到這了,更多相關(guān)Vue Dialog彈窗問(wèn)題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue3 SFC 和 TSX 方式自定義組件實(shí)現(xiàn) v-model的詳細(xì)
v-model 是 vue3 中的一個(gè)內(nèi)置指令,很多表單元素都可以使用這個(gè)屬性,如 input、checkbox 等,咱可以在自定義組件中實(shí)現(xiàn) v-model,這篇文章主要介紹了Vue3 SFC 和 TSX 方式自定義組件實(shí)現(xiàn) v-model,需要的朋友可以參考下2022-10-10
vue3與webpack5安裝element-plus樣式webpack編譯報(bào)錯(cuò)問(wèn)題解決
這篇文章主要介紹了vue3與webpack5安裝element-plus樣式webpack編譯報(bào)錯(cuò),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04
element-ui動(dòng)態(tài)添加表單項(xiàng)并實(shí)現(xiàn)事件觸發(fā)驗(yàn)證代碼示例
這篇文章主要給大家介紹了關(guān)于element-ui動(dòng)態(tài)添加表單項(xiàng)并實(shí)現(xiàn)事件觸發(fā)驗(yàn)證的相關(guān)資料,其實(shí)就是利用了vue的v-for循環(huán)渲染,通過(guò)添加數(shù)組實(shí)現(xiàn)動(dòng)態(tài)添加表單項(xiàng),需要的朋友可以參考下2023-12-12
vue復(fù)合組件實(shí)現(xiàn)注冊(cè)表單功能
這篇文章主要為大家詳細(xì)介紹了vue復(fù)合組件實(shí)現(xiàn)注冊(cè)表單功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
vue directive全局自定義指令實(shí)現(xiàn)按鈕級(jí)別權(quán)限控制的操作方法
這篇文章主要介紹了vue directive全局自定義指令實(shí)現(xiàn)按鈕級(jí)別權(quán)限控制,本文結(jié)合實(shí)例代碼對(duì)基本概念做了詳細(xì)講解,需要的朋友可以參考下2023-02-02
Vue中動(dòng)態(tài)路由加載與ESLint錯(cuò)誤排查全指南
在現(xiàn)代前端開(kāi)發(fā)中,Vue.js?結(jié)合?Webpack?的動(dòng)態(tài)路由加載能顯著提升應(yīng)用性能,本文將通過(guò)一個(gè)實(shí)際案例,詳細(xì)分析動(dòng)態(tài)路由加載的常見(jiàn)錯(cuò)誤,希望對(duì)大家有所幫助2025-04-04

