34條我能告訴你的Vue之實操篇
7種元件通訊方式隨你選
元件通訊是Vue
的核心知識,掌握這幾個知識點,面試開發一點問題都沒有。
props/@on+$emit
用於實現父子元件間通訊。通過props
可以把父元件的訊息傳遞給子元件:
//parent.vue
<child:title="title"></child>
//child.vue
props:{
title:{
type:String,
default:'',
}
}
這樣一來this.title
就直接拿到從父元件中傳過來的title
的值了。注意,你不應該在子元件內部直接改變prop
,這裡就不多贅述,可以直接看官網介紹。
而通過@on+$emit
//parent.vue
<child@changeTitle="changeTitle"></child>
//child.vue
this.$emit('changeTitle','bubuzou.com')
attrs和listeners
Vue_2.4
中新增的$attrs/$listeners
可以進行跨級的元件通訊。$attrs
包含了父級作用域中不作為prop
的屬性繫結(class
和style
除外),好像聽起來有些不好理解?沒事,看下程式碼就知道是什麼意思了:
//父元件index.vue <listclass="list-box"title="標題"desc="描述":list="list"></list>
//子元件list.vue
props:{
list:[],
},
mounted(){
console.log(this.$attrs)//{title:"標題",desc:"描述"}
}
在上面的父元件index.vue
中我們給子元件list.vue
傳遞了4個引數,但是在子元件內部props
裡只定義了一個list
,那麼此時this.$attrs
的值是什麼呢?首先要去除props
中已經綁定了的,然後再去除class
和style
,最後剩下title
和desc
結果和列印的是一致的。基於上面程式碼的基礎上,我們在給list.vue
中加一個子元件:
// 子元件 list.vue <detail v-bind="$attrs"></detial>
//孫子元件detail.vue
//不定義props,直接列印$attrs
mounted(){
console.log(this.$attrs)//{title:"標題",desc:"描述"}
}
在子元件中我們定義了一個v-bind="$attrs"
可以把父級傳過來的引數,去除props
、class
和style
之後剩下的繼續往下級傳遞,這樣就實現了跨級的元件通訊。
$attrs
是可以進行跨級的引數傳遞,實現父到子的通訊;同樣的,通過$listeners
用類似的操作方式可以進行跨級的事件傳遞,實現子到父的通訊。$listeners
包含了父作用域中不含.native
修飾的v-on
事件監聽器,通過v-on="$listeners"
傳遞到子元件內部。
//父元件index.vue
<list@change="change"@update.native="update"></list>
//子元件list.vue
<detailv-on="$listeners"></detail>
//孫子元件detail.vue
mounted(){
this.$listeners.change()
this.$listeners.update()//TypeError:this.$listeners.updateisnotafunction
}
provide/inject組合拳
provide/inject
組合以允許一個祖先元件向其所有子孫後代注入一個依賴,可以注入屬性和方法,從而實現跨級父子元件通訊。在開發高階元件和元件庫的時候尤其好用。
//父元件index.vue
data(){
return{
title:'bubuzou.com',
}
}
provide(){
return{
detail:{
title:this.title,
change:(val)=>{
console.log(val)
}
}
}
}
//孫子元件detail.vue
inject:['detail'],
mounted(){
console.log(this.detail.title)//bubuzou.com
this.detail.title='helloworld'//雖然值被改變了,但是父元件中title並不會重新渲染
this.detail.change('改變後的值')//執行這句後將列印:改變後的值
}
❝❞
provide
和inject
的繫結對於原始型別來說並不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監聽的物件,那麼其物件的 property 還是可響應的。這也就是為什麼在孫子元件中改變了title
,但是父元件不會重新渲染的原因。
EventBus
以上三種方式都是隻能從父到子方向或者子到父方向進行元件的通訊,而我就比較牛逼了