欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue2?Dialog彈窗函數(shù)式調(diào)用實踐示例

 更新時間:2023年01月15日 16:12:41   作者:xekin  
這篇文章主要為大家介紹了Vue2?Dialog彈窗函數(shù)式調(diào)用實踐示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

Dialog 對話框組件幾乎是每個前端項目必不可少的組件,通常是在保留當前頁面狀態(tài)并屏蔽其他用戶輸入的情況下,與用戶交互并承載相關操作。

在 BOM 的方法中,alert、prompt 都是以前用來做類似功能的方法,但是這些瀏覽器內(nèi)置方法會完全停止網(wǎng)頁代碼執(zhí)行,對于貧乏的前端線程資源來說實在是過于僵硬。于是便產(chǎn)生了各種各樣的 Js 彈窗。

今天就來談談在前端框架 Vue 2 版本中的彈窗組件的相關實現(xiàn)以及我個人認為的最佳實踐。

Vue2 的彈窗常用的使用方式

對于 Vue2 的 UI 框架,坊間比較火的有 element-ui antd-vue vant-ui 等等,不過他們在彈窗的使用方法上幾乎都是一致的。下面我們以 element-ui 中的組件為例講講這些使用方式的缺點。

第一種:將彈窗寫在上下文中

這種方式不用多講,使用起來肯定是最麻煩的一種,這意味著你每次想使用這個彈窗組件都要寫一遍負責顯隱的狀態(tài)以及方法,盡量只在唯一場景里使用,不具備復用條件。

第二種:原型上注入全局方法

即是通過往 Vue.prototype 中注入彈窗的方法,使你可以在 vue 上下文中使用 this.$confirm 諸如此類的方法來使用他們的彈窗功能。

這種調(diào)用方式曾經(jīng)幾乎是所有 vue2 全局 api 的解決方法,一時間各種插件都有了各種各樣的全局 api。例如 vuex 的 this.$store、 EventBus 的 this.$bus 等等。

這種方式在使用上雖然非常方便,但也有如下一些缺點

上下文污染,一個 vue 的全局 this 里面,什么東西都可以有,不論是全局方法、還是全局變量,都可以放在 Vue.prototype 里面,例如前一個例子,如果復雜的彈窗需要在各種其他前端文件內(nèi)打開,大概率也是用這種方式將彈窗打開和關閉方法都注入到全局 this 中使用。

類型丟失,無論你是全局狀態(tài)管理還是事件總線,在使用的時候都是各種黑盒,全局方法來自于什么插件、需要傳什么參數(shù)、返回什么東西,全然無感,只能想辦法尋找蛛絲馬跡去溯源。

只能在 vue 上下文中使用,在 vue 文件外就無法使用了。就好比 React 無法在 React 上下文之外 setState 一樣難受。

第三種:通過依賴注入的方式

這種方式和第二種幾乎一樣,通過頂層組件 provider 出對應的函數(shù)方法,之后在子組件中 inject 進來。 一樣存在著 provider 的上下文污染,也丟失了類型,并且依舊只能在 vue 上下文中使用,靈活性一樣差。

合理的使用方式

除了上述所說的問題之外

綜合以上的缺點,我認為一個彈窗最佳的使用方式在 Vue2 中使用方式是這樣:

    <template>
        <button @click="open">打開彈窗</button>
    </template>
    <script>
        import openDialog from 'my-dialog'
        export default {
            methods: {
                open() {
                    openDialog()
                        .then(() => {})
                        .catch(() => {})
                        .finally(() => {})
                }
            }
        }
    </script>

也可以在其他文件中,例如:

    // api.ts
    import openDialog from 'my-dialog'
    const getUserInfo = () => {
        return fetch('/xxx/api').then(() => {
            openDialog('success')
        })
    }

功能實現(xiàn)

廢話不多說,直接上核心代碼

// dialog.ts
import Vue, { ComponentInstance } from "vue";
import ConfirmDialog from "./confirm-dialog.vue";
export let index = 1000;
export const cache = new Set<string>();
export function openDialog(component: ComponentInstance) {
	const div = document.createElement("div");
	const el = document.createElement("div");
	const id = 'dialog-' + Math.random();
	div.appendChild(el);
	document.body.appendChild(div);
	const ComponentConstructor = Vue.extend(component);
	return (propsData = {}, parent = undefined) => {
		let instance = new ComponentConstructor({
			propsData,
			parent,
		}).$mount(el);
		const destroyDialog = () => {
			if (cache.has(id)) return;
			if (instance && div.parentNode) {
				cache.add(id);
				(instance as any).visible = false;
                // 延時是為了在關閉動畫執(zhí)行完畢后卸載組件
				setTimeout(() => {
					cache.delete(id);
					instance.$destroy();
					// @ts-ignore
					instance = null;
					div.parentNode && div.parentNode.removeChild(div);
				}, 1000);
			}
		};
		// visible控制
		if ((instance as any).visible !== undefined) {
			// 支持sync/v-model
			instance.$watch("visible", (val) => {
				!val && destroyDialog();
			});
			Vue.nextTick(() => ((instance as any).visible = true));
		}
		return new Promise((resolve, reject) => {
			// emit 一個 done 事件關閉
			instance.$once("done", (data: any) => {
				destroyDialog();
				resolve(data);
			});
			// emit 一個 cancel 事件取消
			instance.$once("cancel", (data: any) => {
				destroyDialog();
				reject(data);
			});
		});
	};
}
export function confirmDialog(content: string, editable?: boolean) {
	return openDialog(ConfirmDialog as any)({ content, editable });
}

使用方式和結(jié)果可以通過下面這個例子進行查看

stackblitz.com/edit/vitejs…

在例子中,我們可以將任意 vue 組件包裝進 openDialog Api 中,只需要在組件的 data 里寫入一個 visible 屬性,而后續(xù)在組件方法中調(diào)用 this.$emits('done') 或者 this.$emits('cancel') 就可以對應 openDialog 方法返回 Promise 的 then 回調(diào)和 catch 回調(diào)。

可以自定義傳參、自定義內(nèi)容、自定義事件,自定義返回,靈活性直接拉滿。

而且,方法不限于任何上下文,在任何文件內(nèi)都可以使用,實現(xiàn)了真正的函數(shù)式調(diào)用 Vue2 的彈窗組件。

但是這個方法確實也有那么一點點不方便的地方,如果有掘友看得出來,可以在評論下方說說。

結(jié)語

這篇文章其實沒多少東西,甚至代碼都是我一年多前就寫的,在受到 React hooks 的啟發(fā)后,我就覺得函數(shù)式編程非常的爽,就嘗試將項目中的全局變量都剝離 vue 上下文,包括 dialog、message 組件,之后摒棄 vuexpinia 這種強綁上下文的狀態(tài)管理庫,改用 Vue.observable,就可以很方便的將業(yè)務與 UI 完全抽離。所有變量和方法都可以通過 import 追溯,更重要的是這種模式更契合 typescript,類型提示也很輕易跟上來了。

以上就是本篇文章的所有內(nèi)容了,后續(xù)我會封裝 v2 和 v3 的函數(shù)式彈窗組件,并發(fā)布到 npm 上,到時候再更新鏈接到文章里,更多關于Vue2 Dialog彈窗函數(shù)式調(diào)用的資料請關注腳本之家其它相關文章!

相關文章

  • 解決vue 退出動畫無效的問題

    解決vue 退出動畫無效的問題

    這篇文章主要介紹了解決vue 退出動畫無效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 傳說中VUE的語法糖到底是做什么的

    傳說中VUE的語法糖到底是做什么的

    從接觸Vue我們就知道 v-model是實現(xiàn)數(shù)據(jù)雙向綁定的那他能實現(xiàn)綁定的原理到底是啥?最常見的語法糖 v-model,今天通過案例給大家詳細介紹下,需要的朋友參考下吧
    2021-09-09
  • Vue3 響應式高階用法之triggerRef()的使用

    Vue3 響應式高階用法之triggerRef()的使用

    在Vue3響應式系統(tǒng)中,shallowRef僅追蹤頂層屬性的變化,當需要對內(nèi)層屬性作出反應時,可使用triggerRef()方法手動觸發(fā)更新,本文介紹了triggerRef()的應用場景、基本用法、功能和最佳實踐,感興趣的可以了解一下
    2024-09-09
  • Pinia 的 Setup Stores 語法使用實例詳解

    Pinia 的 Setup Stores 語法使用實例詳解

    這篇文章主要為大家介紹了Pinia 的 Setup Stores 語法使用實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • vue使用socket與服務端進行通信的代碼詳解

    vue使用socket與服務端進行通信的代碼詳解

    這篇文章主要給大家介紹了vue如何使用socket與服務端進行通信的相關資料,在Vue中我們可以將Websocket類封裝成一個Vue插件,以便全局使用,需要的朋友可以參考下
    2023-09-09
  • Vue實現(xiàn)todo應用的示例

    Vue實現(xiàn)todo應用的示例

    這篇文章主要介紹了Vue實現(xiàn)todo應用的示例,幫助大家更好的理解和學習使用vue框架,感興趣的朋友可以了解下
    2021-02-02
  • vue axios post發(fā)送復雜對象問題

    vue axios post發(fā)送復雜對象問題

    現(xiàn)在vue項目中,一般使用axios發(fā)送請求去后臺拉取數(shù)據(jù)。這篇文章主要介紹了vue axios post發(fā)送復雜對象的一點思考,需要的朋友可以參考下
    2019-06-06
  • Vue3中實現(xiàn)歌詞滾動顯示效果

    Vue3中實現(xiàn)歌詞滾動顯示效果

    本文分享如何在Vue 3中實現(xiàn)一個簡單的歌詞滾動效果,我將從歌詞數(shù)據(jù)的處理開始,一步步介紹布局的搭建和事件的實現(xiàn),感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • 詳解讓sublime text3支持Vue語法高亮顯示的示例

    詳解讓sublime text3支持Vue語法高亮顯示的示例

    本篇文章主要介紹了讓sublime text3支持Vue語法高亮顯示的示例,非常具有實用價值,需要的朋友可以參考下
    2017-09-09
  • 自帶氣泡提示的vue校驗插件(vue-verify-pop)

    自帶氣泡提示的vue校驗插件(vue-verify-pop)

    這篇文章主要為大家詳細介紹了自帶氣泡提示的vue校驗插件,vue-verify-pop的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04

最新評論