inheritAttrs
組件的根元素是否繼承不被認(rèn)作 props的特性,默認(rèn)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結(jié)構(gòu)钝荡,結(jié)構(gòu)如下
在2.4中新增選項(xiàng)inheritAttrs inheritAttrs的默認(rèn)值為true, 將inheritAttrs的值設(shè)為false, 這些默認(rèn)的行為會(huì)禁止掉。
//子組件
<template>
<div>
<p>foo:{{foo}}</p>
</div>
</template>
<script>
export default {
name:'child-dom',
props:["foo"],
inheritAttrs:false,
}
</script>
但是通過實(shí)例屬性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屬性將父組件的數(shù)據(jù)傳遞給子組件植阴、孫子組件
注意:
$attrs僅包含了父作用域中不作為 prop 被識(shí)別的特性 (class 和 style 除外)
那么問題來了,孫子組件的信息怎么同步給父組件呢圾浅?下面我們就來解決這個(gè)問題
vm.$listeners
vue2.4版本新增了
$listeners
屬性掠手,它是一個(gè)對(duì)象,里面包含了作用在這個(gè)組件上的所有監(jiān)聽器狸捕,有了這個(gè)$listeners
屬性喷鸽,你就可以配合v-on="$listeners"
將所有的事件監(jiān)聽器指向這個(gè)組件的某個(gè)特定的子元素。
我們?cè)谧咏M件上 綁定v-on=”$listeners”
, 就可以在父組件中監(jiān)聽孫子組件觸發(fā)的事件灸拍,就能把孫子組件發(fā)出的數(shù)據(jù)做祝,傳遞給父組件砾省。
//父組件
<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;//改變數(shù)據(jù)
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">我要發(fā)射火箭</button>
</div>
</template>
<script>
export default {
name:'childDomChild',
props:['coo'],
methods:{
startUpRocket(){
this.$emit("upRocket",'簡單我的簡單');
}
}
}
</script>
至此,孫子組件向父組件傳遞數(shù)據(jù)的問題也解決了
綜上所述:vm.$attrs
和 vm.$listeners
可以解決“父組件”和“子組件”混槐、“孫子組件”编兄、“曾孫子組件”等后代組件的通訊問題
- inheritAttrs
默認(rèn)情況下父作用域的不被認(rèn)作 props 的特性綁定 (attribute bindings) 將會(huì)“回退”且作為普通的 HTML 特性應(yīng)用在子組件的根元素上。當(dāng)撰寫包裹一個(gè)目標(biāo)元素或另一個(gè)組件的組件時(shí)声登,這可能不會(huì)總是符合預(yù)期行為狠鸳。通過設(shè)置 inheritAttrs 為 false,這些默認(rèn)行為將會(huì)被去掉悯嗓。而通過 (同樣是 2.4 新增的) 實(shí)例屬性 $attrs 可以讓這些特性生效件舵,且可以通過 v-bind 顯性的綁定到非根元素上。
注意:這個(gè)選項(xiàng)不影響 class 和 style 綁定脯厨。
- vm.$attrs
包含了父作用域中不作為 prop 被識(shí)別的特性綁定 (class 和 style 除外)铅祸。當(dāng)一個(gè)組件沒有聲明任何 prop 時(shí),這里會(huì)包含所有父作用域的綁定 (class 和 style 除外)俄认,并且可以通過 v-bind="$attrs" 傳入內(nèi)部組件——在創(chuàng)建多級(jí)的組件時(shí)非常有用个少。
- vm.$listeners
包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器。它可以通過
v-on="$listeners"
傳入內(nèi)部組件——在創(chuàng)建更高層次的組件時(shí)非常有用眯杏。