這里暫時(shí)僅介紹下“非prop特性(attr)”
一般的特性是顯式定義的(即 prop特性),如下面代碼中的 post ,用于從外部(一般是父組件)向該組件傳入數(shù)據(jù)。不過寫子組件的人并不可能提前預(yù)見該組件會(huì)被如何使用,也就不知道該組件會(huì)被傳入哪些特性。為了提高組件的可用性,組件可以接受任意的特性,那些未在組件中顯式定義的非prop特性,會(huì)被添加到這個(gè)組件的根元素 $attrs上,如第二段代碼和圖片所示:注意 組件中顯式定義的props特性 post 和 組件中未提前定義的非props特性 non-prop 從父組件傳入后,在組件內(nèi)部存儲(chǔ)的位置。
Vue.component('blog-post',{
data:function () {
return {
inputText:'waiting for input...'
}
},
props:{
post:Object
},
...
);
let vm=new Vue({
el:"#posts-demo",
data:{
posts:[
{ id:1,
title:'title1',
content:'<p>content1</p>'},
{ id:2,
title:'title2',
content:'<p>content2</p>'}
],
// 用來傳給blog-post組件的非prop特性(即blog-post組件并未顯式定義該prop特性)
nonProp:'一個(gè)非prop特性的值'
}, })
<blog-post v-for="post in posts"
:post="post"
:non-prop="nonProp"
>
</blog-post>

組件blog-post經(jīng)過渲染呈現(xiàn)在頁面上,非prop特性會(huì)被作為普通的html元素的屬性,如下圖所示。

在Vue2.4.0,可以在組件的定義中設(shè)置 inheritAttrs: false ,這樣渲染組件的時(shí)候就不會(huì)將非prop特性處理為普通的html元素的屬性,而通過該組件的 $attrs還是可以獲取到非prop特性。如下:
Vue.component('blog-post',{
props:{
post:Object
},
inheritAttrs:false,
...
}

有時(shí)候會(huì)有這樣的場(chǎng)景,組件 blog-post 接收了其父組件傳入的非prop 特性 non-prop,此特性在組件 blog-post 并不會(huì)被直接使用,而是要在組件 blog-post 的子組件 custom-input 中使用,那么可以在組件 blog-post 中借助 $attrs 來將其傳給子組件。這也算是從祖父組件A經(jīng)過子組件B向?qū)O子組件C傳遞數(shù)據(jù)的一個(gè)方法吧。
Vue.component('blog-post',{
data: ...,
props:{
post:Object
},
template:`
<div class="blog-post">
...
<custom-input
v-model="inputText"
:passData="$attrs"
>
</custom-input>
...
</div>
`,
...

不過上面的寫法 :passData="$attrs" ,造成了在組件custom-input 中使用的時(shí)候還要 $attrs.passData.non-prop,不夠直接,推薦這樣寫 v-bind="$attrs",效果如圖:
