★2019 前端進(jìn)階之路★Vue 組件間通信實(shí)戰(zhàn)干貨嚷兔!

初體驗(yàn)

Vue.js 在現(xiàn)今使用有多廣泛不用多說(shuō),而 Vue 的一大特點(diǎn)就是組件化做入。本期要講的冒晰,便是 Vue 組件間通信方式的總結(jié),這也幾乎是近年 Vue 面試中的必考題竟块。注:文中示例都基于 Vue 腳手架講解壶运,會(huì)用到一些?Element UI?示例。

【前端進(jìn)階之路】會(huì)作為一個(gè)新系列連載浪秘,后續(xù)會(huì)更多優(yōu)質(zhì)前端內(nèi)容蒋情,感興趣的同學(xué)不妨關(guān)注一下。

①組件

組件是可以復(fù)用的 Vue 實(shí)例耸携。 —?Vue 官方文檔棵癣;

在進(jìn)入主題之前,還是決定先簡(jiǎn)單聊聊組件夺衍。在 Vue 中狈谊,根據(jù)注冊(cè)方式的不同,可以分為:

?????局部組件 (局部注冊(cè))

?????全局組件 (全局注冊(cè))

顧名思義沟沙,全局注冊(cè)的組件河劝,可以用在 Vue 實(shí)例的任意模板中。但是帶來(lái)的隱患是矛紫,在 webpack 模塊化構(gòu)建時(shí)赎瞎,即便你沒(méi)有在項(xiàng)目中使用這個(gè)組件,依然會(huì)打包到最終的項(xiàng)目代碼中含衔。而局部組件煎娇,則需要在使用到的實(shí)例中注冊(cè)該組件二庵。

根據(jù)應(yīng)用場(chǎng)景的不同,又可以分為:

????1.頁(yè)面組件:我們使用 Vue 時(shí)缓呛,每個(gè)路由代表的頁(yè)面催享,都可以稱之為組件。

????2.基礎(chǔ)組件:就像上面栗子中的 Icon 組件哟绊,就是一個(gè)典型的基礎(chǔ)組件因妙。基本上不摻雜業(yè)務(wù)邏輯票髓,在項(xiàng)目中可能被大量使用攀涵,易于移植。類似的基礎(chǔ)組件還有 Button洽沟、Input 等以故,常見(jiàn)于各類 UI 組件庫(kù)。

????3.業(yè)務(wù)組件:業(yè)務(wù)組件和項(xiàng)目具體的業(yè)務(wù)邏輯有大量耦合裆操,一般抽離于當(dāng)前項(xiàng)目怒详。

以上就是組件的簡(jiǎn)單介紹,那我們到底為什么要推崇組件化踪区?組件化有什么好處昆烁?復(fù)用?我個(gè)人認(rèn)為組件化最大的好處缎岗,便是解耦静尼,易于項(xiàng)目管理。所以在大型項(xiàng)目管理中传泊,組件化是非常有必要的鼠渺。當(dāng)然,這并不是今天學(xué)習(xí)的重點(diǎn)眷细,以后有機(jī)會(huì)再聊系冗。

正因?yàn)樵?Vue 中處處都是組件,而我們也偏向于組件化薪鹦、模塊化。那我們?cè)谝欢呀M件中惯豆,便需要解決一個(gè)問(wèn)題 — 組件間通信池磁。下面,我們就進(jìn)入今天的主題楷兽,Vue 的組件間通信地熄。

②組件間通信

組件間通信是我們?cè)?Vue 項(xiàng)目中不可避免的問(wèn)題,深刻了解了 Vue 組件間通信的幾種方式芯杀,才能讓我們?cè)谔幚砀鞣N交互問(wèn)題時(shí)游刃有余端考。

Props

Vue 中雅潭,最基本的通信方式就是 Props,它是父子組件通信中父組件傳值給子組件的一種方式却特。它允許以數(shù)組形式接收扶供,但是更推薦你開(kāi)啟類型檢查的形式。更詳細(xì)的類型檢查前往?vue prop文檔裂明。

我們都知道椿浓,Props 是單向數(shù)據(jù)流,這是 Vue 為了避免子組件意外改變父組件的狀態(tài)闽晦,從而導(dǎo)致數(shù)據(jù)流向難以理解而做出的限制扳碍。所以 Vue 推薦需要改動(dòng)的時(shí)候,通過(guò)改變父組件的值從而觸發(fā) Props 的響應(yīng)仙蛉∷癯ǎ或者,我們可以在接收非引用類型的值時(shí)荠瘪,使用子組件自身的 data 做一次接收夯巷。

為什么是非引用類型呢,因?yàn)樵?JavaScript 中巧还,引用類型的賦值鞭莽,實(shí)際是內(nèi)存地址的傳遞。所以上面栗子中的簡(jiǎn)單賦值麸祷,顯然會(huì)指向同一個(gè)內(nèi)存地址澎怒,所以如果是數(shù)組或是對(duì)象,你可能需要一次深拷貝阶牍。

上面這個(gè)操作有一些缺陷喷面,不能序列化函數(shù)、undefined走孽、循環(huán)引用等……

事實(shí)上惧辈,在 Props 是引用類型時(shí),單獨(dú)修改對(duì)象磕瓷、數(shù)組的某個(gè)屬性或下標(biāo)盒齿,Vue 并不會(huì)拋出錯(cuò)誤。當(dāng)然困食,前提是你要非常清楚自己在做什么边翁,并寫好注釋,防止你的小伙伴們疑惑硕盹。

有的同學(xué)可能知道符匾,在組件上綁定的屬性,如果沒(méi)有在組件內(nèi)部用 Props 聲明瘩例,會(huì)默認(rèn)綁定到組件的根元素上去啊胶。還是之前的栗子:

結(jié)果如下:

這是 Vue 默認(rèn)處理的甸各,而且,除了 class 和 style 采用合并策略焰坪,其它特性(如上栗 type)會(huì)替換掉原來(lái)根元素上的屬性值趣倾。當(dāng)然,我們也可以顯示的在組件內(nèi)部關(guān)閉掉這個(gè)特性:

利用 inheritAttrs琳彩,我們還可以方便的把組件綁定的其它特性誊酌,轉(zhuǎn)移到我們指定的元素上。這就需要用到下一個(gè)我們要講的?$attrs?了露乏。

attrs碧浊、listeners

我們?cè)谑褂媒M件庫(kù)的時(shí)候經(jīng)常會(huì)這么寫:

實(shí)際渲染后:

可以看到我們指定的的 placeholder 是渲染在 input 上的,但是 input 并不是根元素瘟仿。難道都用 Props 聲明后箱锐,再賦值給 input?這種情況就可以用到?$attrs?了劳较,改造一下我們之前那個(gè)栗子驹止。


可以看到粤铭,type 已經(jīng)轉(zhuǎn)移到了子元素 input 標(biāo)簽上垢油,但是 class 沒(méi)有。這是因?yàn)閕nheritAttrs: false選項(xiàng)不會(huì)影響 style 和 class 的綁定虱肄。可以看出$attrs則是將沒(méi)有被組件內(nèi)部 Props 聲明的傳值(也叫非 Props 特性)收集起來(lái)的一個(gè)對(duì)象墓捻,再通過(guò) v-bind 將其綁定在指定元素上抖仅。這也是 Element 等組件庫(kù)采用的策略。

這里需要注意一點(diǎn)砖第,通過(guò) $attrs 指定給元素的屬性撤卢,不會(huì)與該元素原有屬性發(fā)生合并或替換,而是以原有屬性為準(zhǔn)梧兼。舉個(gè)例子放吩,假如我將上述 input 的 type 默認(rèn)設(shè)置為 password。

則不會(huì)采用 $attrs 中的 type: 'text'羽杰,將以 password 為準(zhǔn)渡紫,所以如果需要默認(rèn)值的屬性,建議不要用這種方式考赛。

$listeners同$attrs類似腻惠,可以看做是一個(gè)包含了組件上所有事件監(jiān)聽(tīng)器(包括自定義事件、不包括.native修飾的事件)的對(duì)象欲虚。它也支持上述的寫法,適用于將事件安放于組件內(nèi)指定元素上悔雹。

給之前的栗子綁定一個(gè)聚焦事件复哆,在子組件中通過(guò)$listeners綁定給 input欣喧,則會(huì)在 input 聚焦時(shí)觸發(fā)。

那么除了用在這種給組件內(nèi)指定元素綁定特性和事件的情況梯找,還有哪些場(chǎng)景可以用到呢唆阿?官方說(shuō)明:在創(chuàng)建更高層次的組件時(shí)非常有用。比如在祖孫組件中傳遞數(shù)據(jù)锈锤,在孫子組件中觸發(fā)事件后要在祖輩中做相應(yīng)更新驯鳖。我們繼續(xù)之前的栗子:在孫輩組件觸發(fā)點(diǎn)擊事件,然后在祖輩中修改相應(yīng)的 data久免。

這樣就能很方便的在多級(jí)組件的子級(jí)組件中浅辙,快速訪問(wèn)到父組件的數(shù)據(jù)和方法。正如在剛才的例子中阎姥,button 點(diǎn)擊時(shí)记舆,是直接調(diào)用的 communication.vue 中定義的方法。

總結(jié):

1呼巴、子組件觸達(dá)父組件的方式:Props泽腮、$parent、$attrs衣赶、$listeners诊赊、provide 和 inject、$dispatch

2府瞄、父組件觸達(dá)子組件的方式:$emit和$on碧磅、$children、$ref摘能、broadcast

3续崖、全局通信:EventBus、Vuex

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末团搞,一起剝皮案震驚了整個(gè)濱河市严望,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逻恐,老刑警劉巖像吻,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異复隆,居然都是意外死亡拨匆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門挽拂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)惭每,“玉大人,你說(shuō)我怎么就攤上這事√ㄐ龋” “怎么了宏赘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)黎侈。 經(jīng)常有香客問(wèn)我察署,道長(zhǎng),這世上最難降的妖魔是什么峻汉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任贴汪,我火速辦了婚禮,結(jié)果婚禮上休吠,老公的妹妹穿的比我還像新娘扳埂。我一直安慰自己,他們只是感情好蛛碌,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布聂喇。 她就那樣靜靜地躺著,像睡著了一般蔚携。 火紅的嫁衣襯著肌膚如雪希太。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天酝蜒,我揣著相機(jī)與錄音誊辉,去河邊找鬼。 笑死亡脑,一個(gè)胖子當(dāng)著我的面吹牛堕澄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播霉咨,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蛙紫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了途戒?” 一聲冷哼從身側(cè)響起坑傅,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎喷斋,沒(méi)想到半個(gè)月后唁毒,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡星爪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年浆西,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片顽腾。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡近零,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情久信,我是刑警寧澤猪瞬,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站入篮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏幌甘。R本人自食惡果不足惜潮售,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锅风。 院中可真熱鬧酥诽,春花似錦、人聲如沸皱埠。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)边器。三九已至训枢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間忘巧,已是汗流浹背恒界。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砚嘴,地道東北人十酣。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像际长,于是被迫代替她去往敵國(guó)和親耸采。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容工育,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容虾宇。關(guān)于...
    云之外閱讀 5,046評(píng)論 0 29
  • 前言 您將在本文當(dāng)中了解到,往網(wǎng)頁(yè)中添加數(shù)據(jù),從傳統(tǒng)的dom操作過(guò)渡到數(shù)據(jù)層操作,實(shí)現(xiàn)同一個(gè)目標(biāo),兩種不同的方式....
    itclanCoder閱讀 25,761評(píng)論 1 12
  • 組件(Component)是Vue.js最核心的功能,也是整個(gè)架構(gòu)設(shè)計(jì)最精彩的地方翅娶,當(dāng)然也是最難掌握的文留。...
    六個(gè)周閱讀 5,584評(píng)論 0 32
  • vue概述 在官方文檔中,有一句話對(duì)Vue的定位說(shuō)的很明確:Vue.js 的核心是一個(gè)允許采用簡(jiǎn)潔的模板語(yǔ)法來(lái)聲明...
    li4065閱讀 7,191評(píng)論 0 25
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,204評(píng)論 0 6