1. 程式人生 > 實用技巧 >34條我能告訴你的Vue之實操篇

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的屬性繫結(classstyle除外),好像聽起來有些不好理解?沒事,看下程式碼就知道是什麼意思了:

//父元件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中已經綁定了的,然後再去除classstyle,最後剩下titledesc結果和列印的是一致的。基於上面程式碼的基礎上,我們在給list.vue中加一個子元件:

// 子元件 list.vue
<detail v-bind="$attrs"></detial>
//孫子元件detail.vue
//不定義props,直接列印$attrs
mounted(){
console.log(this.$attrs)//{title:"標題",desc:"描述"}
}

在子元件中我們定義了一個v-bind="$attrs"可以把父級傳過來的引數,去除propsclassstyle之後剩下的繼續往下級傳遞,這樣就實現了跨級的元件通訊。

$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('改變後的值')//執行這句後將列印:改變後的值
}

provideinject的繫結對於原始型別來說並不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監聽的物件,那麼其物件的 property 還是可響應的。這也就是為什麼在孫子元件中改變了title,但是父元件不會重新渲染的原因。

EventBus

以上三種方式都是隻能從父到子方向或者子到父方向進行元件的通訊,而我就比較牛逼了