国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Vue.js 父子組件通信的十種方式

網絡 通信技術
無可否認,現在無論大廠還是小廠都已經用上了 Vue.js 框架,簡單易上手不說,教程詳盡,社區活躍,第三方套件還多。

 [[266702]]

面試官:Vue 中父子組件通信有哪些方式?

自己先想一分鐘。

無可否認,現在無論大廠還是小廠都已經用上了 Vue.js 框架,簡單易上手不說,教程詳盡,社區活躍,第三方套件還多。

真的是前端開發人員必備技能。

而且在面試當中也往往會問到關于 Vue 方面的各種問題,其中大部分面試官會問到如上這種問題。

最近一直在做 Vue項目代碼層面上的優化,說實話,優化別人的代碼真是件痛苦的事情,功能實現尚且不說,就說代碼規范我就能再寫出一篇文章來。

真的是無規范不成方圓,規范這個東西太重要了!

有點扯了,回到主題,咳咳,那就談談我對上面的面試題的理解吧,文筆有限,不妥之處,歡迎在文章結尾留言斧正啊,正啊,啊!

概述

幾種通信方式無外乎以下幾種:

  • Prop(常用)
  • $emit (組件封裝用的較多)
  • .sync語法糖 (較少)
  • $attrs 和 $listeners (組件封裝用的較多)
  • provide 和 inject (高階組件/組件庫用的較多)
  • 其他方式通信

詳述

下面逐個介紹,大神請繞行。

1. Prop

英式發音:[prɒp]。

這個在我們日常開發當中用到的非常多。

簡單來說,我們可以通過 Prop 向子組件傳遞數據。

用一個形象的比喻來說,父子組件之間的數據傳遞相當于自上而下的下水管子,只能從上往下流,不能逆流。

這也正是 Vue 的設計理念之單向數據流。

而 Prop 正是管道與管道之間的一個銜接口,這樣水(數據)才能往下流。說這么多,看代碼:

  1. <div id="app">  <child :content="message"></child></div> 
  2. // Js 
  3. let Child = Vue.extend({ 
  4.   template: '<h2>{{ content }}</h2>'
  5.   props: { 
  6.     content: { 
  7.       type: String, 
  8.       default: () => { return 'from child' } 
  9.     } 
  10.   } 
  11. }) 
  12.  
  13. new Vue({ 
  14.   el: '#app'
  15.   data: { 
  16.     message: 'from parent' 
  17.   }, 
  18.   components: { 
  19.     Child 
  20.   } 
  21. }) 

 

 

 

瀏覽器輸出:

  1. from parent 

2. $emit

英式發音:[iˈmɪt]。

官方說法是觸發當前實例上的事件。

附加參數都會傳給監聽器回調。

按照我的理解不知道能不能給大家說明白,先簡單看下代碼吧:

  1. <div id="app">  <my-button @greet="sayHi"></my-button></div> 
  2. let MyButton = Vue.extend({ 
  3.   template: '<button @click="triggerClick">click</button>'
  4.   data () { 
  5.     return { 
  6.       greeting: 'vue.js!' 
  7.     } 
  8.   }, 
  9.   methods: { 
  10.     triggerClick () { 
  11.       this.$emit('greet', this.greeting) 
  12.     } 
  13.   } 
  14. }) 
  15.  
  16. new Vue({ 
  17.   el: '#app'
  18.   components: { 
  19.     MyButton 
  20.   }, 
  21.   methods: { 
  22.     sayHi (val) { 
  23.       alert('Hi, ' + val) // 'Hi, vue.js!' 
  24.     } 
  25.   } 
  26. }) 

 

大致邏輯是醬嬸兒的:當我在頁面上點擊按鈕時,觸發了組件 MyButton 上的監聽事件 greet,并且把參數傳給了回調函數 sayHi 。

說白了,當我們從子組件 Emit(派發) 一個事件之前,其內部都提前在事件隊列中 On(監聽)了這個事件及其監聽回調。其實相當于下面這種寫法:

  1. vm.$on('greet'function sayHi (val) {  console.log('Hi, ' + val)})vm.$emit('greet''vue.js')// => "Hi, vue.js" 

3. .sync 修飾符

這個家伙在 vue@1.x 的時候曾作為雙向綁定功能存在,即子組件可以修改父組件中的值。

因為它違反了單向數據流的設計理念,所以在 vue@2.0 的時候被干掉了。

但是在 vue@2.3.0+ 以上版本又重新引入了這個 .sync 修飾符。

但是這次它只是作為一個編譯時的語法糖存在。

它會被擴展為一個自動更新父組件屬性的 v-on 監聽器。

說白了就是讓我們手動進行更新父組件中的值了,從而使數據改動來源更加的明顯。

下面引入自官方的一段話:

在有些情況下,我們可能需要對一個 prop 進行“雙向綁定”。

不幸的是,真正的雙向綁定會帶來維護上的問題,因為子組件可以修改父組件,且在父組件和子組件都沒有明顯的改動來源。

既然作為一個語法糖,肯定是某種寫法的簡寫形式,哪種寫法呢,看代碼:

  1. <text-document  v-bind:title="doc.title"  v-on:update:title="doc.title = $event"></text-document> 

于是我們可以用 .sync 語法糖簡寫成如下形式:

  1. <text-document v-bind:title.sync="doc.title"></text-document> 

廢話這么多,如何做到“雙向綁定” 呢?

讓我們進段廣告,廣告之后更加精彩!

... 好的,歡迎回來。

假如我們想實現這樣一個效果:改變子組件文本框中的值同時改變父組件中的值。

怎么做?列位不妨先想想。先看段代碼:

  1. <div id="app">  <login :name.sync="userName"></login> {{ userName }}</div> 
  2. let Login = Vue.extend({ 
  3.   template: ` 
  4.     <div class="input-group"
  5.       <label>姓名:</label> 
  6.       <input v-model="text"
  7.     </div> 
  8.   `, 
  9.   props: ['name'], 
  10.   data () { 
  11.     return { 
  12.       text: '' 
  13.     } 
  14.   }, 
  15.   watch: { 
  16.     text (newVal) { 
  17.       this.$emit('update:name', newVal) 
  18.     } 
  19.   } 
  20. }) 
  21.  
  22. new Vue({ 
  23.   el: '#app'
  24.   data: { 
  25.     userName: '' 
  26.   }, 
  27.   components: { 
  28.     Login 
  29.   } 
  30. }) 

 

下面劃重點,代碼里有這一句話:

  1. this.$emit('update:name', newVal) 

官方語法是:update:myPropName 其中 myPropName 表示要更新的 prop 值。

當然如果你不用 .sync 語法糖使用上面的 .$emit 也能達到同樣的效果。僅此而已!

4. $attrs 和 $listeners

  • 官網對 $attrs 的解釋如下:

包含了父作用域中不作為 prop 被識別 (且獲取) 的特性綁定 (class 和 style 除外)。

當一個組件沒有聲明任何 prop 時,這里會包含所有父作用域的綁定 (class 和 style 除外),并且可以通過 v-bind="$attrs" 傳入內部組件——在創建高級別的組件時非常有用。

  • 官網對 $listeners 的解釋如下:

包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監聽器。

它可以通過 v-on="$listeners" 傳入內部組件——在創建更高層次的組件時非常有用。

我覺得 $attrs 和 $listeners 屬性像兩個收納箱,一個負責收納屬性,一個負責收納事件,都是以對象的形式來保存數據。

看下面的代碼解釋:

  1. <div id="app">  <child    :foo="foo"    :bar="bar"    @one.native="triggerOne"    @two="triggerTwo">  </child></div> 

 

 

從 Html 中可以看到,這里有倆屬性和倆方法,區別是屬性一個是 prop 聲明,事件一個是 .native 修飾器。

  1. let Child = Vue.extend({ 
  2.   template: '<h2>{{ foo }}</h2>'
  3.   props: ['foo'], 
  4.   created () { 
  5.     console.log(this.$attrs, this.$listeners) 
  6.     // -> {bar: "parent bar"
  7.     // -> {two: fn} 
  8.  
  9.  
  10.     // 這里我們訪問父組件中的 `triggerTwo` 方法 
  11.     this.$listeners.two() 
  12.     // -> 'two' 
  13.   } 
  14. }) 
  15.  
  16. new Vue({ 
  17.   el: '#app'
  18.   data: { 
  19.     foo: 'parent foo'
  20.     bar: 'parent bar' 
  21.   }, 
  22.   components: { 
  23.     Child 
  24.   }, 
  25.   methods: { 
  26.       triggerOne () { 
  27.       alert('one'
  28.     }, 
  29.     triggerTwo () { 
  30.       alert('two'
  31.     } 
  32.   } 
  33. }) 

 

 

可以看到,我們可以通過 $attrs 和 $listeners 進行數據傳遞,在需要的地方進行調用和處理,還是很方便的。

當然,我們還可以通過 v-on="$listeners" 一級級的往下傳遞,子子孫孫無窮盡也!

一個插曲!

當我們在組件上賦予了一個非Prop 聲明時,編譯之后的代碼會把這些個屬性都當成原始屬性對待,添加到 html 原生標簽上,看上面的代碼編譯之后的樣子:

  1. <h2 bar="parent bar">parent foo</h2> 

 

這樣會很難看,同時也爆了某些東西。

如何去掉?

這正是 inheritAttrs 屬性的用武之地!

給組件加上這個屬性就行了,一般是配合 $attrs 使用。

看代碼:

  1. // 源碼let Child = Vue.extend({  ...  inheritAttrs: false, // 默認是 true  ...}) 

再次編譯:

  1. <h2>parent foo</h2> 

 

5. provide / inject

他倆是對CP, 感覺挺神秘的。

來看下官方對 provide / inject 的描述:

provide 和 inject 主要為高階插件/組件庫提供用例。

并不推薦直接用于應用程序代碼中。

并且這對選項需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在起上下游關系成立的時間里始終生效。

看完描述有點懵懵懂懂!

一句話總結就是:小時候你老爸什么東西都先幫你存著等你長大該娶媳婦兒了你要房子給你買要車給你買只要他有的盡量都會滿足你。

下面是這句話的代碼解釋:

  1. <div id="app">  <son></son></div> 
  2. let Son = Vue.extend({ 
  3.   template: '<h2>son</h2>'
  4.   inject: { 
  5.     house: { 
  6.       default'沒房' 
  7.     }, 
  8.     car: { 
  9.       default'沒車' 
  10.     }, 
  11.     money: { 
  12.       // 長大工作了雖然有點錢 
  13.       // 僅供生活費,需要向父母要 
  14.       default'¥4500' 
  15.     } 
  16.   }, 
  17.   created () { 
  18.     console.log(this.house, this.car, this.money) 
  19.     // -> '房子''車子''¥10000' 
  20.   } 
  21. }) 
  22.  
  23. new Vue({ 
  24.   el: '#app'
  25.   provide: { 
  26.     house: '房子'
  27.     car: '車子'
  28.     money: '¥10000' 
  29.   }, 
  30.  
  31.   components: { 
  32.     Son 
  33.   } 
  34. }) 

 

6. 其他方式通信

除了以上五種方式外,其實還有:

  • EventBus

思路就是聲明一個全局Vue實例變量 EventBus , 把所有的通信數據,事件監聽都存儲到這個變量上。

這樣就達到在組件間數據共享了,有點類似于 Vuex。

但這種方式只適用于極小的項目,復雜項目還是推薦 Vuex。

下面是實現 EventBus 的簡單代碼:

  •  
  1. <div id="app">  <child></child></div> 
  2. // 全局變量 
  3. let EventBus = new Vue() 
  4.  
  5. // 子組件 
  6. let Child = Vue.extend({ 
  7.   template: '<h2>child</h2>'
  8.   created () { 
  9.     console.log(EventBus.message) 
  10.     // -> 'hello' 
  11.     EventBus.$emit('received''from child'
  12.   } 
  13. }) 
  14.  
  15. new Vue({ 
  16.   el: '#app'
  17.   components: { 
  18.     Child 
  19.   }, 
  20.   created () { 
  21.     // 變量保存 
  22.     EventBus.message = 'hello' 
  23.     // 事件監聽 
  24.     EventBus.$on('received'function (val) { 
  25.       console.log('received: '+ val) 
  26.       // -> 'received: from child' 
  27.     }) 
  28.   } 
  29. }) 

 

 

  • Vuex

官方推薦的,Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。

  • $parent

父實例,如果當前實例有的話。

通過訪問父實例也能進行數據之間的交互,但極小情況下會直接修改父組件中的數據。

  • $root

當前組件樹的根 Vue 實例。

如果當前實例沒有父實例,此實例將會是其自己。

通過訪問根組件也能進行數據之間的交互,但極小情況下會直接修改父組件中的數據。

  • broadcast / dispatch

他倆是 vue@1.0 中的方法,分別是事件廣播 和 事件派發。

雖然 vue@2.0 里面刪掉了,但可以模擬這兩個方法。

可以借鑒 Element 實現。

有時候還是非常有用的,比如我們在開發樹形組件的時候等等。

總結

啰嗦了這么多,希望看到的同學或多或少有點收獲吧。

不對的地方還請留言指正,不勝感激。

父子組件間的通信其實有很多種,就看你在哪些情況下去用。

不同場景不同對待。

前提是你要心中有數才行!

通過大神之路還有很遠,只要每天看看社區,看看文檔,寫寫Demo,每天進步一點點,總會有收獲的。

責任編輯:武曉燕 來源: 前端大牛愛好者
相關推薦

2024-01-09 08:34:56

Vue3.js組件通信

2019-11-27 15:30:32

人工智能機器人技術

2017-06-30 08:51:12

組件模板勒索軟件項目管理

2020-09-12 16:22:27

Vue

2021-09-15 08:09:43

前端技術編程

2018-12-04 21:05:51

2011-12-21 21:16:58

2022-06-15 10:44:12

通貨膨脹IT

2019-04-10 08:24:06

vue組件通信

2019-08-14 10:00:08

vue組件通信前端

2020-09-16 06:12:30

Vue.js 3.0Suspense組件前端

2017-07-11 18:00:21

vue.js數據組件

2020-11-26 20:54:23

AI人工智能建筑

2021-11-11 14:31:11

大數據人工智能

2022-07-15 08:48:07

IT通貨膨脹IT支出

2022-08-26 16:44:40

智慧城市AI人工智能

2014-12-12 10:29:28

SaaS云服務

2017-07-03 16:03:49

IT技術周刊

2017-12-11 16:25:25

2016-12-08 10:53:46

程序員編程
點贊
收藏

51CTO技術棧公眾號

国产高清久久久久| 亚洲欧美日韩网| 在线电影欧美日韩一区二区私密| 欧美亚洲日本在线观看| 亚洲欧美综合在线精品| 天天综合网天天做天天受| 精品对白一区国产伦| 狠狠色丁香久久婷婷综合_中 | 综合久久2o19| 91麻豆蜜桃一区二区三区| 99在线视频播放| 欧美体内she精视频在线观看| 国产欧美一区二区在线播放| 美腿丝袜亚洲图片| 色婷婷av久久久久久久| 欧美在线一卡| 日日噜噜噜夜夜爽亚洲精品 | 亚洲国产精品二十页| 国产国语**毛片高清视频| 成人黄色激情网| 亚洲精品久久久久久久久久久久 | 日韩精品一区二区在线| 岛国最新视频免费在线观看| 欧美性xxxxxx| 国模精品一区二区| 亚洲精品黄网在线观看| 国产高清不卡| 国产喷白浆一区二区三区| 狼狼综合久久久久综合网| 成人爽a毛片| 亚洲一区二区久久久| 亚洲精品动漫| 久久久久久久久久久成人| 在线免费观看欧美| 国产做受高潮69| 久久精品国产免费| 亚洲欧美影院| 国产剧情一区| 国产精品白嫩初高中害羞小美女 | 亚洲精品小说| 精品视频高清无人区区二区三区| 久久先锋资源网| аⅴ资源新版在线天堂| 亚洲精品ady| 日韩精品一级| 99久久精品无码一区二区毛片| 日韩国产欧美在线观看| 91九色视频导航| 欧美日韩一卡| av日韩在线免费| 亚洲第一页在线| 综合视频在线| 欧美少妇性生活视频| 日韩精品在线看| 日韩中文字幕一区二区三区| 日p在线观看| 欧美在线视频日韩| 黄色大片在线播放| 欧美另类老女人| 国产视频亚洲| 国产毛片久久久久久国产毛片| 日韩经典中文字幕一区| 欧美黄网在线观看| 午夜精品久久久久久久99黑人| 青青草视频一区| 在线影院av| 国产日韩欧美在线观看| 五月婷婷久久丁香| 天堂中文字幕| 国产成人亚洲欧美| 天堂久久一区| 91玉足脚交白嫩脚丫在线播放| 色香蕉在线观看| 久久99久久99| 男人日女人逼逼| 国产精品免费久久| 一级特黄视频| 欧美猛男gaygay网站| 9999精品成人免费毛片在线看| 国产午夜精品麻豆| 国产精品白丝久久av网站| 国产成人一区二区三区电影| 日韩欧美精品一区| 日本一区二区在线| 久久夜色精品国产欧美乱极品| 男女无套免费网站| 在线91免费看| 麻豆一区在线| 国产日本欧美在线观看| 蓝色福利精品导航| 蜜桃传媒九九九| 欧美日韩国产另类一区| 日韩影片中文字幕| 国产精品久久久久久久久久| 国内自拍视频一区二区三区| 亚洲韩国在线| 亚洲青青青在线视频| 男女羞羞视频教学| 大荫蒂欧美视频另类xxxx| 亚洲丝袜一区| 国产一区二区三区免费视频| 农村少妇一区二区三区四区五区 | 亚洲欧洲二区| 欧美有码在线观看视频| 亚洲成人二区| 亚洲ai欧洲av| 久久综合999| 亚洲52av| 日韩高清有码在线| 国内毛片久久| 成人免费在线视频网址| 粉嫩一区二区三区在线看| 色婷婷av金发美女在线播放| 欧美一级片免费看| a级日韩大片| 国产欧美精品一区二区三区| 久久av资源站| 日本免费视频| 欧美精品在线一区二区| 波多野结衣在线一区二区| 精品毛片久久久久久| 久久日一线二线三线suv| 免费成人av电影| 色av吧综合网| 午夜精品久久| 免费看又黄又无码的网站| 精品视频1区2区3区| 亚洲网一区二区三区| 久久久久久久久久码影片| 国产目拍亚洲精品99久久精品| 香蕉视频网站在线观看| 欧美激情视频网址| 视频一区二区中文字幕| 我看黄色一级片| 亚洲精品国精品久久99热| 禁断一区二区三区在线| 阿v天堂2018| 欧美性色黄大片| 琪琪久久久久日韩精品| 亚洲一卡二卡三卡四卡无卡网站在线看| 日本一区二区三区在线观看| 黄色网在线免费观看| 91免费欧美精品| 国产欧美一区二区精品秋霞影院 | 激情五月五月婷婷| 亚洲国产精品欧美一二99| 91p九色成人| 欧美伦理一区二区| 精品欧美激情精品一区| 欧美高清xxx| 天堂一区二区三区| 韩曰欧美视频免费观看| 亚洲精品福利| 伊人情人网综合| 在线一区二区视频| 91成人超碰| julia京香一区二区三区| 欧美巨大黑人极品精男| 国产suv一区二区三区88区| 成人黄色网址| 国产在线欧美日韩| 欧美日韩性视频| 日韩精品久久| 在线欧美成人| 91久久极品少妇xxxxⅹ软件| 疯狂欧美牲乱大交777| 国产999精品久久久| 精品一卡二卡三卡四卡日本乱码 | 2021av在线| 18一19gay欧美视频网站| 国产欧美一区二区精品秋霞影院 | 国内揄拍国内精品| 久久都是精品| 美女网站视频在线| 久久国产日韩欧美| 精品精品国产高清a毛片牛牛| 成人vr资源| 中国动漫在线观看完整版免费| 九九综合九九综合| 性欧美18一19内谢| 亚洲三级视频在线观看| 亚洲第一二三区| 99视频免费| 国产日产欧美精品| 欧美日韩精品在线观看| 欧美日韩午夜| 97超碰国产一区二区三区| 国产精品揄拍500视频| 欧美在线免费视屏| 日韩天堂av| 亚洲成人av观看| 久久av高潮av| 7777免费精品视频| 亚洲永久精品国产| 国产农村妇女精品一二区| av免费网站在线观看| 国产黄页在线观看| 午夜精品久久久久久久99热| 成人午夜视频免费看| 欧美1区2区3|