摘要:接下來(lái),由簡(jiǎn)入繁依次實(shí)現(xiàn)提示組件的各個(gè)功能。那么第一個(gè)提示的定時(shí)器依然會(huì)錯(cuò)誤的關(guān)閉新提示。增強(qiáng)靈活性最后則是讓提示組件更靈活。
這次的教程里,我們要把組件化進(jìn)行到底!最近半年的幾個(gè)項(xiàng)目中,都遇到了需要使用Toast或者Notification組件的情況。在目前已有的一些基于Vue.js開發(fā)的組件庫(kù),都沒有找到太合適的,所以自己重頭實(shí)現(xiàn)了一個(gè)。歷經(jīng)幾個(gè)項(xiàng)目的磨練,這個(gè)提示組件的功能已經(jīng)越來(lái)越完善,這次就分享一下組件以及其實(shí)現(xiàn)思路吧。
深入組件化,組件的拆分、整合與復(fù)用GitHub 倉(cāng)庫(kù):https://github.com/Yuyz0112/vue-notie
Demo 地址:http://lab.myriptide.com/vue-notie/
Vue.js的組件化可以說(shuō)是其招牌特性之一,而在實(shí)際應(yīng)用時(shí),并非一味地追求組件顆粒越小越好,而是需要根據(jù)項(xiàng)目的實(shí)際需求,來(lái)分析自己需要什么級(jí)別的組件。
例如在一個(gè)SPA中,我可能有主頁(yè)、文章列表頁(yè)、文章頁(yè)、個(gè)人中心頁(yè)4個(gè)主要的視圖,于是我將其分別對(duì)應(yīng)的寫成4個(gè)組件。
但是在實(shí)際編寫的過(guò)程中,發(fā)現(xiàn)他們共用了同一套側(cè)邊欄,而側(cè)邊欄對(duì)應(yīng)的代碼也在4個(gè)組件中重復(fù)書寫了4次。所以可以將側(cè)邊欄多帶帶寫成一個(gè)組件進(jìn)行復(fù)用。
之后,我們可能發(fā)現(xiàn)可以復(fù)用的還有一些表單、按鈕之類的內(nèi)容我們都可以復(fù)用成組件。但實(shí)際上,我們也會(huì)發(fā)現(xiàn)過(guò)度的組件化會(huì)導(dǎo)致代碼量上升、開發(fā)時(shí)間增加以及額外的數(shù)據(jù)傳遞等等。所以如果不打算制作一個(gè)完整的組件庫(kù),那么在實(shí)際項(xiàng)目中做到按需拆分、整合即可,不用過(guò)分的追求每個(gè)可復(fù)用的部分都寫成單個(gè)組件。
為什么需要一個(gè)提示組件因?yàn)閍lert大部分時(shí)間不能滿足我們的需求啊。往往項(xiàng)目里需要一個(gè)類似于alert的東西,用美觀、可定制的方式提示用戶一些信息,因此這樣一個(gè)提示組件很有必要。
同時(shí),我們也不希望同一時(shí)間出現(xiàn)多個(gè)提示混淆用戶,因此在設(shè)計(jì)上,我們將提示組件設(shè)定為具有唯一性,整個(gè)應(yīng)用中各個(gè)視圖調(diào)用的都是同一個(gè)提示組件。
Show me the code接下來(lái),由簡(jiǎn)入繁依次實(shí)現(xiàn)提示組件的各個(gè)功能。
基本功能最基本的功能當(dāng)然是觸發(fā)后顯示,并且能夠以某種方式關(guān)閉。唯一需要自定義的部分,就是具體顯示的內(nèi)容。所以最開始組件長(zhǎng)這樣:
{{ options.content }}
思路很簡(jiǎn)單,props傳遞兩個(gè)數(shù)據(jù),show用于控制顯示,options傳入包括內(nèi)容在內(nèi)的自定義內(nèi)容。為了讓提示的顯示更加自然,添加了一個(gè)滑動(dòng)進(jìn)入和離開的transition。
注意:這里的關(guān)閉按鈕是通過(guò)css實(shí)現(xiàn)的,如果在你的項(xiàng)目中有對(duì)應(yīng)的icon,可以將其替換掉。
在此處,也可以使用slot來(lái)進(jìn)行內(nèi)容的傳遞,但考慮到之后還有別的參數(shù)需要傳遞至組件內(nèi),一次用一個(gè)統(tǒng)一的對(duì)象options進(jìn)行傳遞。
自定義樣式通常提示的內(nèi)容種類很多,有的是成功提示,有的是警告,有的則是報(bào)錯(cuò)。因此我們需要定義不同的樣式以表達(dá)不同的內(nèi)容。
方法很簡(jiǎn)單,在options中傳入背景色和文字顏色兩個(gè)參數(shù),如果組件中檢測(cè)到了傳入的樣式參數(shù),就用其替換默認(rèn)樣式。
Vue.js在處理動(dòng)態(tài)樣式時(shí)非常靈活,為了讓代碼更清晰,我沒有選擇將動(dòng)態(tài)樣式內(nèi)聯(lián),而是多帶帶使用一個(gè)計(jì)算屬性setStyle進(jìn)行設(shè)定:
computed: { setStyle () { return { color: this.options.textColor || "#fff", background: this.options.backgroundColor || "#21e7b6" } } }
這樣一來(lái),只要在options中一并傳入textColor和backgroundColor兩個(gè)屬性,就可以輕松自定義提示樣式了。
自動(dòng)關(guān)閉很多時(shí)候,我們希望提示在一定時(shí)間之后可以自動(dòng)關(guān)閉,因此組件也需要擴(kuò)展出一個(gè)自動(dòng)關(guān)閉的模式。同樣的,在“數(shù)據(jù)驅(qū)動(dòng)”的思想下,我們應(yīng)該提供一個(gè)數(shù)據(jù),用來(lái)表明這個(gè)提示是否自動(dòng)關(guān)閉。
options中的autoClose屬性就是這個(gè)作用。同樣的,自動(dòng)關(guān)閉的延遲時(shí)間顯然也要能夠自定義,因此還一同添加了showTime這一屬性。
自動(dòng)關(guān)閉本身不太復(fù)雜,我們只需要使用setTimeout,定義一個(gè)計(jì)時(shí)器即可。
首先是監(jiān)聽提示組件的顯示。
在這里,我通過(guò)watch監(jiān)聽options的變化來(lái)處罰計(jì)時(shí)器。由于我們已經(jīng)定義了一個(gè)close方法用于關(guān)閉計(jì)時(shí)器,并且在關(guān)閉時(shí)重置了show和options的值,所以在options變化時(shí),只需要判斷options中的autoClose是否為true,就能知道是否需要啟動(dòng)計(jì)時(shí)器了。這里多帶帶使用一個(gè)countdown方法來(lái)處理定時(shí)器相關(guān)的操作。
新增代碼如下:
data () { return { timers: [] } }, methods: { countdown () { if (this.options.autoClose) { const t = setTimeout(() => { this.close() }, this.options.showTime || 3000) this.timers.push(t) } } }, watch: { options () { this.timers.forEach((timer) => { window.clearTimeout(timer) }) this.timers = [] this.countdown() } }
細(xì)心地你肯定會(huì)發(fā)現(xiàn),這段代碼中,有一些奇怪的處理。我們定義了一個(gè)空數(shù)組timers,并且每次開始一個(gè)計(jì)時(shí)器的時(shí)候,就把計(jì)時(shí)器存入數(shù)組中,而每次options變化時(shí),我們也從timers中遍歷所有計(jì)時(shí)器并取消,之后清空timers。
這個(gè)做法,主要是為了避免一個(gè)計(jì)時(shí)器還沒有結(jié)束時(shí),又開始一個(gè)新的提示所引發(fā)的提示被提前關(guān)閉的清空。舉個(gè)例子,如果沒有這樣的處理,那么先發(fā)出一個(gè)自動(dòng)關(guān)閉的提示,在其沒自動(dòng)關(guān)閉之前,就再發(fā)出一個(gè)新的提示。那么第一個(gè)提示的定時(shí)器依然會(huì)錯(cuò)誤的關(guān)閉新提示。
這樣的問(wèn)題主要是由于我們所有的計(jì)時(shí)器都是在同一個(gè)組件中,本質(zhì)上都是同一個(gè)提示,因此需要清除計(jì)時(shí)器,避免沖突。許多組件庫(kù)中類似的功能組件,是采用每一條提示就新生成一個(gè)提示組件的方式來(lái)實(shí)現(xiàn)的。但是那樣在多個(gè)提示連續(xù)出現(xiàn)時(shí),就會(huì)出現(xiàn)堆疊在一起,又各自離開的情況。
之前的版本中,我的提示組件也采用了類似的設(shè)計(jì)方式,但是在最近的一個(gè)項(xiàng)目中,需要實(shí)現(xiàn)半透明的提示組件,就出現(xiàn)了堆疊后看不清提示文字的現(xiàn)象,才使用了現(xiàn)在新的模式。
進(jìn)一步擴(kuò)展緊接著,我拓展了一個(gè)自動(dòng)關(guān)閉模式下的倒計(jì)時(shí)條功能。思路上沒有使用Vue.js的transition系統(tǒng),而是采用了Css3本身的動(dòng)畫系統(tǒng)。在一個(gè)自動(dòng)關(guān)閉的提示被初始化時(shí),為計(jì)時(shí)條添加一個(gè)樣式,效果是向X軸負(fù)方向移動(dòng)100%,transition時(shí)間則通過(guò)計(jì)算屬性對(duì)應(yīng)設(shè)定。具體實(shí)現(xiàn)可以參考源代碼,這里不多做贅述。
增強(qiáng)靈活性最后則是讓提示組件更靈活。有的時(shí)候,我們想展示的可能是可以自定義樣式的文本、亦或是一個(gè)超鏈接甚至更多。而Vue.js實(shí)現(xiàn)起來(lái)不要太簡(jiǎn)單。我們只需要將組件中用于渲染的{{ options.content }}變?yōu)?b>{{{ options.content }}}即可,對(duì)于3重花括號(hào)的模板,Vue.js會(huì)將其中的HTML標(biāo)簽按照正常內(nèi)容渲染。
如此一來(lái),我們就可以將任何HTML內(nèi)容放入提示中了。當(dāng)然一定要注意避免將用戶輸入的內(nèi)容渲染到3重花括號(hào)的模板中,避免XSS攻擊。
結(jié)合vuex很多時(shí)候,我們會(huì)把提示組件引入到App.vue這個(gè)根組件中,但是發(fā)出提示的可能是組件樹中的任何一個(gè)組件。如果不想代碼中遍布各種dispatch和broadcast,那么引入vuex來(lái)進(jìn)行管理是個(gè)很好的方案。
大致的思路如下:
// store.js const state = { show: false, options: { autoClose: false, content: "notice content" } } const mutations = { NEW_NOTICE (state, options) { state.show = true state.options = options }, CLOSE_NOTICE (state) { state.show = false state.options = {} } } // actions.js export const newNotice = ({dispatch}, options) => { dispatch("NEW_NOTICE", options) } export const closeNotice = ({dispatch}) => { dispatch("CLOSE_NOTICE") } // Notification.vue vuex: { getters: { show: state => state.show options: state => state.options }, actions: { close: closeNotice } } // 任意調(diào)用notice的組件 vuex: { actions: { notice: newNotice } }
引入vuex后,按上述代碼進(jìn)行配置,就可以在任意一處組件中,使用this.notice({options})傳遞數(shù)據(jù)。不過(guò)由于vuex的單項(xiàng)數(shù)據(jù)流動(dòng)特性,所有對(duì)state數(shù)據(jù)的操作都必須經(jīng)過(guò)actions調(diào)用mutations實(shí)現(xiàn),包括提示組件中的close方法也要替換成actions中的closeNotice方法。
綜述通過(guò)這個(gè)提示組件,我們更熟練的掌握了Vue.js的組件系統(tǒng)、數(shù)據(jù)傳遞、計(jì)算屬性、transition動(dòng)畫等特性。另外此組件已經(jīng)可以直接用于生產(chǎn)環(huán)境中,歡迎star、fork、pr。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/79994.html
摘要:前端每周清單第期現(xiàn)狀分析與優(yōu)化策略單元測(cè)試爬蟲作者王下邀月熊編輯徐川前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。 showImg(https://segmentfault.com/img/remote/1460000011008022); 前端每周清單第 29 期:Web 現(xiàn)狀分析與優(yōu)化策略...
摘要:在引起狀態(tài)變化的時(shí)刻,框架自動(dòng)觸發(fā)臟檢查,也可以手動(dòng)執(zhí)行臟檢查,直接操作更新視圖。最后,說(shuō)了這么多,大家在具體選型時(shí)還是要首先分析自己的需求和現(xiàn)狀,然后再做選擇。 作為一個(gè)軟件開發(fā)者,最大的挑戰(zhàn)就是在不斷涌現(xiàn)的新技術(shù)中進(jìn)行取舍,持續(xù)學(xué)習(xí)是從事這一行業(yè)的必備技能。在這個(gè)領(lǐng)域里,技術(shù)更新最快地又非前端莫屬了。各種框架的出現(xiàn)、版本的更新此起彼伏,呈現(xiàn)出一派欣欣向榮之景。 在項(xiàng)目中必不可少的便...
摘要:在引起狀態(tài)變化的時(shí)刻,框架自動(dòng)觸發(fā)臟檢查,也可以手動(dòng)執(zhí)行臟檢查,直接操作更新視圖。最后,說(shuō)了這么多,大家在具體選型時(shí)還是要首先分析自己的需求和現(xiàn)狀,然后再做選擇。 作為一個(gè)軟件開發(fā)者,最大的挑戰(zhàn)就是在不斷涌現(xiàn)的新技術(shù)中進(jìn)行取舍,持續(xù)學(xué)習(xí)是從事這一行業(yè)的必備技能。在這個(gè)領(lǐng)域里,技術(shù)更新最快地又非前端莫屬了。各種框架的出現(xiàn)、版本的更新此起彼伏,呈現(xiàn)出一派欣欣向榮之景。 在項(xiàng)目中必不可少的便...
摘要:在引起狀態(tài)變化的時(shí)刻,框架自動(dòng)觸發(fā)臟檢查,也可以手動(dòng)執(zhí)行臟檢查,直接操作更新視圖。最后,說(shuō)了這么多,大家在具體選型時(shí)還是要首先分析自己的需求和現(xiàn)狀,然后再做選擇。 作為一個(gè)軟件開發(fā)者,最大的挑戰(zhàn)就是在不斷涌現(xiàn)的新技術(shù)中進(jìn)行取舍,持續(xù)學(xué)習(xí)是從事這一行業(yè)的必備技能。在這個(gè)領(lǐng)域里,技術(shù)更新最快地又非前端莫屬了。各種框架的出現(xiàn)、版本的更新此起彼伏,呈現(xiàn)出一派欣欣向榮之景。 在項(xiàng)目中必不可少的便...
閱讀 2034·2023-04-26 00:16
閱讀 3486·2021-11-15 11:38
閱讀 3177·2019-08-30 12:50
閱讀 3188·2019-08-29 13:59
閱讀 759·2019-08-29 13:54
閱讀 2509·2019-08-29 13:42
閱讀 3314·2019-08-26 11:45
閱讀 2195·2019-08-26 11:36