inheritAttrs
組件的根元素是否繼承不被認作 props的特性,默認true
//父組件
<template>
<div>
<child-dom
:foo="foo"
:coo="coo"
>
</child-dom>
</div>
</template>
<script>
import childDom from "../components/Father2-Child";
export default {
data() {
return {
foo:"Hello, world",
coo:"Hello,rui"
}
},
components:{childDom},
}
</script>
//子組件
<template>
<div>
<p>foo:{{foo}}</p>
</div>
</template>
<script>
export default {
name:'child-dom',
props:["foo"],
}
</script>
查看DOM結構,結構如下
在2.4中新增選項inheritAttrs inheritAttrs的默認值為true, 將inheritAttrs的值設為false, 這些默認的行為會禁止掉。
//子組件
<template>
<div>
<p>foo:{{foo}}</p>
</div>
</template>
<script>
export default {
name:'child-dom',
props:["foo"],
inheritAttrs:false,
}
</script>
但是通過實例屬性vm.$attrs ,可以將這些特性生效,且可以通過v-bind 綁定到子組件的非根元素上。
vm.$attrs
//父組件
<template>
<div>
<child-dom
:foo="foo"
:coo="coo"
>
</child-dom>
</div>
</template>
<script>
import childDom from "../components/Father2-Child";
export default {
data() {
return {
foo:"Hello, world",
coo:"Hello,rui"
}
},
components:{childDom},
}
</script>
//子組件
<template>
<div>
<p>foo:{{foo}}</p>
<p>attrs:{{$attrs}}</p>
<childDomChild v-bind="$attrs"></childDomChild>
</div>
</template>
<script>
import childDomChild from '../components/Father2-Child-Child';
export default {
name:'child-dom',
props:["foo"],
inheritAttrs:false,
components:{childDomChild}
}
</script>
//孫子組件
<template>
<div>
<p>coo:{{coo}}</p>
</div>
</template>
<script>
export default {
name:'childDomChild',
props:["coo"],
inheritAttrs:false
}
</script>
綜上所述:可以通過$attrs屬性將父組件的數據傳遞給子組件、孫子組件
注意:
$attrs僅包含了父作用域中不作為 prop 被識別的特性 (class 和 style 除外)
那么問題來了,孫子組件的信息怎么同步給父組件呢?下面我們就來解決這個問題
vm.$listeners
vue2.4版本新增了
$listeners
屬性,它是一個對象,里面包含了作用在這個組件上的所有監聽器,有了這個$listeners
屬性,你就可以配合v-on="$listeners"
將所有的事件監聽器指向這個組件的某個特定的子元素。
我們在子組件上 綁定v-on=”$listeners”
, 就可以在父組件中監聽孫子組件觸發的事件,就能把孫子組件發出的數據,傳遞給父組件。
//父組件
<template>
<div>
{{coo}}
<child-dom
:foo="foo"
:coo="coo"
@upRocket="reciveRocket">
</child-dom>
</div>
</template>
<script>
import childDom from "../components/Father2-Child";
export default {
name:'demoNo',
data() {
return {
foo:"Hello, world",
coo:"Hello,rui"
}
},
components:{childDom},
methods:{
reciveRocket(ev){
this.coo = ev;//改變數據
console.log(this.coo)
}
}
}
</script>
//子組件
<template>
<div>
<p>foo:{{foo}}</p>
<p>attrs:{{$attrs}}</p>
<childDomChild v-bind="$attrs" v-on="$listeners"></childDomChild>
</div>
</template>
<script>
import childDomChild from '../components/Father2-Child-Child';
export default {
name:'child-dom',
props:["foo"],
inheritAttrs:false,
components:{childDomChild}
}
</script>
//孫子組件
<template>
<div>
<p>coo:{{coo}}</p>
<button @click="startUpRocket">我要發射火箭</button>
</div>
</template>
<script>
export default {
name:'childDomChild',
props:['coo'],
methods:{
startUpRocket(){
this.$emit("upRocket",'簡單我的簡單');
}
}
}
</script>
至此,孫子組件向父組件傳遞數據的問題也解決了
綜上所述:vm.$attrs
和 vm.$listeners
可以解決“父組件”和“子組件”、“孫子組件”、“曾孫子組件”等后代組件的通訊問題
- inheritAttrs
默認情況下父作用域的不被認作 props 的特性綁定 (attribute bindings) 將會“回退”且作為普通的 HTML 特性應用在子組件的根元素上。當撰寫包裹一個目標元素或另一個組件的組件時,這可能不會總是符合預期行為。通過設置 inheritAttrs 為 false,這些默認行為將會被去掉。而通過 (同樣是 2.4 新增的) 實例屬性 $attrs 可以讓這些特性生效,且可以通過 v-bind 顯性的綁定到非根元素上。
注意:這個選項不影響 class 和 style 綁定。
- vm.$attrs
包含了父作用域中不作為 prop 被識別的特性綁定 (class 和 style 除外)。當一個組件沒有聲明任何 prop 時,這里會包含所有父作用域的綁定 (class 和 style 除外),并且可以通過 v-bind="$attrs" 傳入內部組件——在創建多級的組件時非常有用。
- vm.$listeners
包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監聽器。它可以通過
v-on="$listeners"
傳入內部組件——在創建更高層次的組件時非常有用。