日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

原生“跨組件”通信方式

來(lái)源: 責(zé)編: 時(shí)間:2023-11-13 17:18:38 354觀看
導(dǎo)讀現(xiàn)在已經(jīng)是“組件化”開發(fā)時(shí)代了。相信大家平時(shí)在vue或者react中都碰到過(guò)“跨組件”通信的需求,通常我們需要將數(shù)據(jù)放在一個(gè)公共的父級(jí)上,然后用context之類的方式傳遞下去,或者借用pinia這樣的開源庫(kù)去更好的管理這些數(shù)

kc428資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)在已經(jīng)是“組件化”開發(fā)時(shí)代了。kc428資訊網(wǎng)——每日最新資訊28at.com

相信大家平時(shí)在vue或者react中都碰到過(guò)“跨組件”通信的需求,通常我們需要將數(shù)據(jù)放在一個(gè)公共的父級(jí)上,然后用context之類的方式傳遞下去,或者借用pinia這樣的開源庫(kù)去更好的管理這些數(shù)據(jù)。kc428資訊網(wǎng)——每日最新資訊28at.com

不過(guò),大部分項(xiàng)目可能沒(méi)有那么復(fù)雜,可能只有極少部分需要“跨組件”通信或者全局傳遞的,專門去引入一個(gè)全局狀態(tài)管理庫(kù)還是有一定成本的,不僅僅是性能開銷,還有學(xué)習(xí)成本。kc428資訊網(wǎng)——每日最新資訊28at.com

另外,還有一些舊項(xiàng)目,由于前期組件設(shè)計(jì)未考慮周全,或者由于后期需求迭代,導(dǎo)致需要跨組件通信,此時(shí)再引入狀態(tài)管理庫(kù)也有很大的改造成本。kc428資訊網(wǎng)——每日最新資訊28at.com

框架用久了,可能有些都忘了,原生 web 并沒(méi)有組件化的概念,整個(gè)頁(yè)面都是開放的,所以,借助原生的一些行為和方式,也能很輕易的解決“跨組件”通信問(wèn)題,下面列舉了幾個(gè)方式,一起看看吧~kc428資訊網(wǎng)——每日最新資訊28at.com

一、label for

舉個(gè)例子,下面是之前做的一個(gè)錯(cuò)別字糾錯(cuò)功能,也就是自動(dòng)檢測(cè)錯(cuò)別字,然后提供替換和忽略一些功能,如下:kc428資訊網(wǎng)——每日最新資訊28at.com

kc428資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)在不用關(guān)注是怎么實(shí)現(xiàn)的,如果按照組件化拆分,右邊的糾錯(cuò)面板肯定是單獨(dú)的組件。kc428資訊網(wǎng)——每日最新資訊28at.com

kc428資訊網(wǎng)——每日最新資訊28at.com

很自然的,關(guān)于忽略的相關(guān)函數(shù)也是寫在這個(gè)組件,類似于這樣。kc428資訊網(wǎng)——每日最新資訊28at.com

<!--糾錯(cuò)組件--><script setup>const ignore = () => {  // 相關(guān)操作}</script><template>...<button @click="ignore">忽略</button>...</template>

嗯,很好,組件化很不錯(cuò),邏輯也很清晰。kc428資訊網(wǎng)——每日最新資訊28at.com

過(guò)了兩天,產(chǎn)品又需要在另外一個(gè)地方也要有“忽略”功能,當(dāng)鼠標(biāo)懸浮的時(shí)候,下拉選項(xiàng)中也有忽略選項(xiàng),并且這兩個(gè)忽略的功能是完全一樣的,如下:kc428資訊網(wǎng)——每日最新資訊28at.com

kc428資訊網(wǎng)——每日最新資訊28at.com

再單獨(dú)實(shí)現(xiàn)一遍肯定是不行的,把這個(gè)函數(shù)抽離出來(lái)?但是還有新的問(wèn)題,整個(gè)錯(cuò)別字的列表也是需要更新的,是不是也要把這個(gè)列表也獨(dú)立出來(lái)?kc428資訊網(wǎng)——每日最新資訊28at.com

no,當(dāng)然不需要這么麻煩,僅需要一個(gè)label標(biāo)簽就可以輕松搞定,如下:kc428資訊網(wǎng)——每日最新資訊28at.com

<!--寫作區(qū)域的下拉組件--><template>...<ui-dropdown>  <label for="AAA">忽略</label>  ...</ui-dropdown>...</template>

當(dāng)然,右邊的忽略按鈕也需要加上一個(gè)相同的ID(實(shí)際中是動(dòng)態(tài)生成的)。kc428資訊網(wǎng)——每日最新資訊28at.com

<!--糾錯(cuò)組件--><template>...<button id="AAA" @click="ignore">忽略</button>...</template>

這樣,通過(guò)label+for就將這兩個(gè)元素關(guān)聯(lián)起來(lái)了,點(diǎn)擊這個(gè)label元素就相當(dāng)于點(diǎn)擊了右邊的忽略按鈕,無(wú)需任何跨組件通信,是不是非常方便呢?kc428資訊網(wǎng)——每日最新資訊28at.com

二、主動(dòng)觸發(fā)事件

有時(shí)候,需要通信的事件可能并不是通過(guò)按鈕點(diǎn)擊的,比如這樣一個(gè)寫作頁(yè)面,按照頁(yè)面布局和功能,各個(gè)部分肯定是單獨(dú)的組件,如下:kc428資訊網(wǎng)——每日最新資訊28at.com

kc428資訊網(wǎng)——每日最新資訊28at.com

其中,右上角有一個(gè)“保存”按鈕,可以保存內(nèi)容,假設(shè)是這樣。kc428資訊網(wǎng)——每日最新資訊28at.com

<!--功能組件--><script setup>const save = () => {  // 相關(guān)操作}</script><template>...<button @click="save">保存</button>...</template>

現(xiàn)在,產(chǎn)品又提出一個(gè)要求,希望在寫作時(shí),按 Ctrl + S也能保存內(nèi)容。kc428資訊網(wǎng)——每日最新資訊28at.com

那么,你會(huì)怎么處理呢?把保存方法封裝一下?全局通信?kc428資訊網(wǎng)——每日最新資訊28at.com

其實(shí),我們要做的事情很簡(jiǎn)單,只需要主動(dòng)去觸發(fā)一下保存按鈕的點(diǎn)擊事件就可以了,當(dāng)然需要獲取到這個(gè)按鈕,所以要加個(gè)ID。kc428資訊網(wǎng)——每日最新資訊28at.com

<!--功能組件--><template>...<button id="saveBtn" @click="save">保存</button>...</template>

然后在寫作組件中直接通過(guò)觸發(fā)click事件就好了。kc428資訊網(wǎng)——每日最新資訊28at.com

<!--寫作組件--><script setup>// Ctrl+S 保存const save = () => {  document.getElementById('saveBtn').click()}</script>

當(dāng)然,我更習(xí)慣于用dispatch的方式來(lái)觸發(fā)。kc428資訊網(wǎng)——每日最新資訊28at.com

document.getElementById('saveBtn').dispatchEvent(new Event('click'))

這樣的好處是不限類型,任意事件都可以觸發(fā),而不僅僅是點(diǎn)擊事件。kc428資訊網(wǎng)——每日最新資訊28at.com

dom.dispatchEvent(new Event('mouseover'))

關(guān)于dispatchEvent,下面還有更靈活的運(yùn)用。kc428資訊網(wǎng)——每日最新資訊28at.com

三、dispatchEvent 和 addEventListener

dispatchEvent不僅可以觸發(fā)常見的點(diǎn)擊事件,也能夠觸發(fā)任意自定義事件。kc428資訊網(wǎng)——每日最新資訊28at.com

舉個(gè)例子,有兩個(gè)相互獨(dú)立的功能區(qū),有兩個(gè)按鈕,分別點(diǎn)擊后,會(huì)做一些操作,比如請(qǐng)求接口,最后會(huì)彈出同一個(gè)獎(jiǎng)勵(lì)彈窗kc428資訊網(wǎng)——每日最新資訊28at.com

kc428資訊網(wǎng)——每日最新資訊28at.com

如果按照組件話的思維來(lái)考慮,可能需要將獎(jiǎng)勵(lì)彈窗的狀態(tài)放在一個(gè)公共的父級(jí),然后依次回調(diào),或者用全局狀態(tài)管理庫(kù)區(qū)管理這些狀態(tài)。kc428資訊網(wǎng)——每日最新資訊28at.com

但是,如果從原生 web 來(lái)考慮,其實(shí)不必那么麻煩,下面是一些偽代碼。kc428資訊網(wǎng)——每日最新資訊28at.com

<!--功能組件A--><script setup>const getPrize = () => {  // 領(lǐng)獎(jiǎng)勵(lì)一系列邏輯}</script><template>...<button @click="getPrize">領(lǐng)獎(jiǎng)勵(lì)A(yù)</button>...</template>

然后還有功能區(qū) B。kc428資訊網(wǎng)——每日最新資訊28at.com

<!--功能組件B--><script setup>const getPrize = () => {  // 領(lǐng)獎(jiǎng)勵(lì)B一系列邏輯}</script><template>...<button @click="getPrize">領(lǐng)獎(jiǎng)勵(lì)B</button>...</template>

然后還有獎(jiǎng)勵(lì)彈窗。kc428資訊網(wǎng)——每日最新資訊28at.com

<!--獎(jiǎng)勵(lì)彈窗--><script>const open = () => {  // 打開彈窗}</script><template>...<dialog>獎(jiǎng)勵(lì)彈窗</dialog>...</template>

那么,怎么讓其他功能區(qū)的組件打開獎(jiǎng)勵(lì)彈窗呢?kc428資訊網(wǎng)——每日最新資訊28at.com

這就需要用自定義事件了,很簡(jiǎn)單,直接觸發(fā)一個(gè)自定義事件,假設(shè)就叫做prize。kc428資訊網(wǎng)——每日最新資訊28at.com

document.dispatchEvent(new CustomEvent('prize'))

放在業(yè)務(wù)組件中就是。kc428資訊網(wǎng)——每日最新資訊28at.com

<!--功能組件A--><script setup>const getPrize = () => {  // 領(lǐng)獎(jiǎng)勵(lì)一系列邏輯  document.dispatchEvent(new CustomEvent('prize'))}</script><template>...<button @click="getPrize">領(lǐng)獎(jiǎng)勵(lì)A(yù)</button>...</template>

然后,我們可以在頁(yè)面任意地方都監(jiān)聽到這個(gè)事件,直接通過(guò)addEventListener就可以了。kc428資訊網(wǎng)——每日最新資訊28at.com

document.addEventListener('prize', () => {  // 監(jiān)聽到了prize})

所以,我們可以把這個(gè)監(jiān)聽直接放在獎(jiǎng)勵(lì)彈窗組件中。kc428資訊網(wǎng)——每日最新資訊28at.com

<!--獎(jiǎng)勵(lì)彈窗--><script>const open = () => {  // 打開彈窗}onMounted(() => {  document.addEventListener('prize', () => {  	// 監(jiān)聽到了prize,打開彈窗    open()	})})</script><template>...<dialog>獎(jiǎng)勵(lì)彈窗</dialog>...</template>

這樣,無(wú)論組件是什么樣的嵌套關(guān)系,都可以隨心所欲地通信了。kc428資訊網(wǎng)——每日最新資訊28at.com

四、最后總結(jié)一下

本文更多的還是提供一種思路,實(shí)際開發(fā)中可以自己權(quán)衡,什么方式比較合適,下面總結(jié)一下這三種方式kc428資訊網(wǎng)——每日最新資訊28at.com

  • label for比較適合于按鈕點(diǎn)擊事件的復(fù)用,可以將label元素與button元素綁定起來(lái)。
  • 相比label for而言,主動(dòng)觸發(fā)事件更靈活,可以觸發(fā)任意事件,無(wú)需button元素,也不限制點(diǎn)擊事件。
  • dispatchEvent 和 addEventListener是最靈活的方式了,幾乎可以做到全局通信,通過(guò)dispatchEvent觸發(fā),然后通過(guò)addEventListener監(jiān)聽。

當(dāng)然,這些方式也不能濫用,畢竟用多了就顯得邏輯混亂,如果全局通信的情況比較多,還是建議使用傳統(tǒng)的組件化方式就行管理。kc428資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-23634-0.html原生“跨組件”通信方式

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: CSS @scope 如何取代 BEM

下一篇: 用了這么多年Docker,殊不知你還有這么多彎彎繞!

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 高碑店市| 双柏县| 南郑县| 柞水县| 天等县| 东光县| 罗江县| 云林县| 高陵县| 镇坪县| 梁平县| 武宁县| 满城县| 高雄市| 城固县| 邮箱| 历史| 犍为县| 瓦房店市| 江源县| 衡阳县| 定兴县| 郯城县| 嵩明县| 镇原县| 建昌县| 容城县| 阿克| 祁门县| 栖霞市| 崇信县| 唐海县| 诸暨市| 塔河县| 大田县| 抚顺县| 富蕴县| 祥云县| 莱西市| 邮箱| 鄢陵县|