摘要:之后再引入該指令,如下之后就可以在組件的模板中使用該指令了,比如一切都將按預(yù)期中運(yùn)行,當(dāng)組件的狀態(tài)為開時(shí),組件的根元素會(huì)增加一個(gè)的內(nèi)容增強(qiáng)屬性。到后來(lái)興起了組件化開發(fā)的開發(fā)思想,指令似乎是隨著的沒落而消失了蹤影。
06 通過 directive 增強(qiáng)組件內(nèi)容 目標(biāo)
之前的五篇文章中,switch 組件一直是被視為內(nèi)部組件存在的,細(xì)心的讀者應(yīng)該會(huì)發(fā)現(xiàn),這個(gè)組件除了幫我們提供開關(guān)的交互以外,還會(huì)根據(jù)當(dāng)前 toggle 的開關(guān)狀態(tài),為 button 元素增加 aria-expanded 屬性,以 aira 開頭的屬性叫作內(nèi)容增強(qiáng)屬性,它用于描述當(dāng)前元素的某種特殊狀態(tài),幫助殘障人士更好地瀏覽網(wǎng)站內(nèi)容。
但是,作為組件調(diào)用者,未必會(huì)對(duì)使用這種相關(guān)屬性對(duì)網(wǎng)站內(nèi)容進(jìn)行增強(qiáng),那么如何更好地解決這個(gè)問題呢?答案就是使用 directive。
我們期望能夠顯示地聲明當(dāng)前的元素是一個(gè) toggler 職能的組件或者元素,這個(gè)組件或者元素,可以根據(jù)當(dāng)前 toggle 組件的開關(guān)狀態(tài),動(dòng)態(tài)地更新它本身的 aria-expanded 屬性,以便針對(duì)無(wú)障礙訪問提供適配。
實(shí)現(xiàn) 簡(jiǎn)單實(shí)現(xiàn)首先創(chuàng)建一個(gè) toggler 指令函數(shù),如下:
export default function(el, binding, vnode) { const on = binding.value if (on) { el.setAttribute(`aria-expanded`, true); } else { el.removeAttribute(`aria-expanded`, false); } }
這個(gè)指令函數(shù)很簡(jiǎn)單,就是通過傳入指令的表達(dá)式的值來(lái)判定,是否在當(dāng)前元素上增加一個(gè) aria-expanded 屬性。之后再 app 引入該指令,如下:
directives: { toggler }
之后就可以在 app 組件的模板中使用該指令了,比如:
一切都將按預(yù)期中運(yùn)行,當(dāng) toggle 組件的狀態(tài)為開時(shí),custom-button 組件的根元素會(huì)增加一個(gè) aria-expanded="true" 的內(nèi)容增強(qiáng)屬性。
Note: 這里關(guān)于指令的引入,使用的函數(shù)簡(jiǎn)寫的方式,會(huì)在指令的 bind 和 update 鉤子函數(shù)中觸發(fā)相同的邏輯,vue 中的指令包含 5 個(gè)不同的鉤子函數(shù),這里就不贅述了,不熟悉的讀者可以通過閱讀官方文檔來(lái)了解。
注入當(dāng)前組件實(shí)例上文中的指令會(huì)通過 binding.value 來(lái)獲取 toggle 組件的開關(guān)狀態(tài),這樣雖然可行,但在使用該指令時(shí),custom-button 本身的 prop 屬性 on 已經(jīng)代表了當(dāng)前的開關(guān)狀態(tài),能否直接在指令中獲取當(dāng)前所綁定的組件實(shí)例呢?答案是可以的。指令函數(shù)的第三個(gè)參數(shù)即為當(dāng)前所綁定組件的虛擬 dom 節(jié)點(diǎn)實(shí)例,其 componentInstance 屬性指向當(dāng)前組件實(shí)例,所以可以將之前的指令改版如下:
export default function(el, binding, vnode) { const comp = vnode.componentInstance; const on = binding.value || comp.on; if (on) { el.setAttribute(`aria-expanded`, true); } else { el.removeAttribute(`aria-expanded`, false); } }
這樣,即使不向指令傳入表達(dá)式,它也可以自動(dòng)去注入當(dāng)前修飾組件所擁有的 prop 屬性 on 的值,如下:
提供更多靈活性
指令函數(shù)的第二個(gè)參數(shù)除了可以獲取傳入指令內(nèi)部的表達(dá)式的值以外,還有其他若干屬性,比如 name、arg、modifiers等,詳細(xì)說(shuō)明可以去參考官方文檔。
為了盡可能地使指令保證靈活性,我們期望可以自定義無(wú)障礙屬性 aria 的后綴名稱,比如叫做 aria-on,這里我們可以通過 arg 這個(gè)參數(shù)輕松實(shí)現(xiàn),改版如下:
export default function(el, binding, vnode) { const comp = vnode.componentInstance; const suffix = binding.arg || "expanded"; const on = binding.value || comp.on; if (on) { el.setAttribute(`aria-${suffix}`, true); } else { el.removeAttribute(`aria-${suffix}`, false); } }
可以發(fā)現(xiàn),這里通過 binding.arg 來(lái)獲取無(wú)障礙屬性的后綴名稱,并當(dāng)沒有傳遞該參數(shù)時(shí),降級(jí)至 expanded。這里僅僅是為了演示,讀者有興趣的話,還可以利用 binding 對(duì)象的其他屬性提供更多的靈活性。
成果最終的運(yùn)行結(jié)果就不用語(yǔ)言描述了,直接截了一個(gè)圖,是 toggle 組件開關(guān)狀態(tài)為開時(shí)的截圖:
你可以下面的鏈接來(lái)看看這個(gè)組件的實(shí)現(xiàn)代碼以及演示:
sandbox: 在線演示
github: part-6
總結(jié)關(guān)于指令的概念,我自身還是在 angularjs(v1.2以下版本) 中第一次接觸,當(dāng)時(shí)其實(shí)不興組件化開發(fā)這個(gè)概念,指令本身的設(shè)計(jì)理念也是基于增強(qiáng)這個(gè)概念的,即增強(qiáng)某個(gè) html 標(biāo)簽。到后來(lái)興起了組件化開發(fā)的開發(fā)思想,指令似乎是隨著 angularjs 的沒落而消失了蹤影。
但仔細(xì)想想的話,web 開發(fā)流程中,并不是所有的場(chǎng)景都可以拿組件來(lái)抽象和描述的,比如說(shuō),你想提供一個(gè)類似高亮邊框的公用功能,到底如何來(lái)按組件化的思想抽象它呢?這時(shí)候使用指令往往是一個(gè)很好的切入點(diǎn)。
因此,當(dāng)你面臨解決的問題,顆粒度小于組件化抽象的粒度,同時(shí)又具備復(fù)用性,那就大膽的使用指令來(lái)解決它吧。
目錄github gist
關(guān)注公眾號(hào) 全棧101,只談技術(shù),不談人生
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/98558.html
摘要:寫在前頭去年,曾經(jīng)閱讀過一系列關(guān)于高級(jí)組件模式的文章,今年上半年,又抽空陸陸續(xù)續(xù)地翻譯了一系列關(guān)于高級(jí)組件模式的文章,碰巧最近接手了一個(gè)公司項(xiàng)目,前端這塊的技術(shù)棧是。同時(shí)這個(gè)組件還擁有一個(gè)屬性,用來(lái)初始化的狀態(tài)值。 寫在前頭 去年,曾經(jīng)閱讀過一系列關(guān)于高級(jí) react 組件模式的文章,今年上半年,又抽空陸陸續(xù)續(xù)地翻譯了一系列關(guān)于高級(jí) angular 組件模式的文章,碰巧最近接手了一個(gè)公...
摘要:調(diào)用全局的守衛(wèi)。在被激活的組件里調(diào)用。用創(chuàng)建好的實(shí)例調(diào)用守衛(wèi)中傳給的回調(diào)函數(shù)。 本文適用于對(duì) Vue.js 和 vue-router 有一定程度了解的開發(fā)者除特殊說(shuō)明,vue-router 版本為 3.0.2 正文 路由 class 匹配 路由匹配后會(huì)給該標(biāo)簽添加 class 屬性值 .router-link-active,該功能在嵌套路由中十分方便 class 的實(shí)際屬性值可以通...
摘要:在中,我們是否也有一些手段或特性來(lái)提高組件的復(fù)用程度和靈活性呢答案當(dāng)然是有的,那就是。成果通過實(shí)現(xiàn),我們成功將注入的邏輯抽離了出來(lái),這樣每次需要共享組件的狀態(tài)和方法時(shí),混入該即可。 03 使用 mixin 來(lái)增強(qiáng) Vue 組件 目標(biāo) 之前一篇文章中,我們雖然將 toggle 組件劃分為了 toggle-button、toggle-on 和 toggle-off 三個(gè)子組件,且一切運(yùn)行良...
摘要:編寫復(fù)合組件目標(biāo)我們需要實(shí)現(xiàn)的需求是能夠使使用者通過組件動(dòng)態(tài)地改變包含在它內(nèi)部的內(nèi)容。成果通過復(fù)合組件的方式,我們將組件劃分為了三個(gè)更小的職責(zé)更加單一的子組件。 02 編寫復(fù)合組件 目標(biāo) 我們需要實(shí)現(xiàn)的需求是能夠使使用者通過 組件動(dòng)態(tài)地改變包含在它內(nèi)部的內(nèi)容。 熟悉 vue 的童鞋可能馬上會(huì)想到不同的解決方案,比如使用 slot 并配合 v-if,我們這里采用另外一種方法,利用 vu...
摘要:并總結(jié)經(jīng)典面試題集各種算法和插件前端視頻源碼資源于一身的文檔,優(yōu)化項(xiàng)目,在瀏覽器端的層面上提升速度,幫助初中級(jí)前端工程師快速搭建項(xiàng)目。 本文是關(guān)注微信小程序的開發(fā)和面試問題,由基礎(chǔ)到困難循序漸進(jìn),適合面試和開發(fā)小程序。并總結(jié)vue React html css js 經(jīng)典面試題 集各種算法和插件、前端視頻源碼資源于一身的文檔,優(yōu)化項(xiàng)目,在瀏覽器端的層面上提升速度,幫助初中級(jí)前端工程師快...
閱讀 3723·2021-10-12 10:11
閱讀 1992·2019-08-30 15:53
閱讀 1598·2019-08-30 13:15
閱讀 2311·2019-08-30 11:25
閱讀 1808·2019-08-29 11:24
閱讀 1657·2019-08-26 13:53
閱讀 3530·2019-08-26 13:22
閱讀 1773·2019-08-26 10:24