編譯作用域
<child-component>
{{message}}
</child-component>
<!--在這里,{{massage}}的數(shù)據(jù)應(yīng)該是父組件的數(shù)據(jù),而不是child-componet的數(shù)據(jù)-->
在vue組件中作用域簡單的說就是:
父組件模板的內(nèi)容在父組件的作用域內(nèi)編譯,子組件模板的內(nèi)容在子組件的作用域內(nèi)編譯
一個常見的錯誤是我們會試圖在父組件內(nèi)將一個指令綁定到子組件的屬性/方法
<child-component v-show="someChildProperty"></child-component>
如果someChildProperty是子組件的屬性,那么這種做法是無效的,在vue中父模板是不應(yīng)該知道子組件狀態(tài)的,如果想要通過子組件的someChildProperty來控制子組件的show/hide,那么應(yīng)該在子組件內(nèi)對其進(jìn)行設(shè)置
單個插槽
在我們使用組件時,父組件在子組件標(biāo)簽內(nèi)寫入的內(nèi)容都會被丟棄,例如
<child-component>
<p>父組件的內(nèi)容</p> <!--不會顯示-->
</child-component>
如果我們想要在子組件渲染時能夠渲染出父組件添加的內(nèi)容,需要為子組件組件中設(shè)置slot插槽
當(dāng)子組件內(nèi)只有一個沒有屬性的插槽時,父組件在調(diào)用子組件時在子組件內(nèi)添加的內(nèi)容將全部插入到插槽所在的DOM節(jié)點的位置,并替換掉插槽標(biāo)簽本身
最初在插槽標(biāo)簽內(nèi)的任何元素都將會被視為默認(rèn)內(nèi)容,默認(rèn)內(nèi)容在子組件的作用域內(nèi)編譯,只有在宿主元素為空,且沒有插入內(nèi)容的時候才顯示
<body>
<div id="box">
<h4>This's parent</h4>
<child>
<h4>推薦好友列表</h4>
<ul>
<li>tom</li>
</ul>
</child>
</div>
<template id="childTem">
<div>
<h4>This's child</h4>
<slot>
<p>您還沒有推薦好友~</p>
</slot>
</div>
</template>
<script>
new Vue({
components:{
'child':{
template:"#childTem"
}
}
}).$mount("#box")
</script>
</body>
具名插槽
slot元素可以用一個特殊的屬性name來配置如何分布內(nèi)容,多個插槽可以有不同的名字,設(shè)置有name屬性的插槽會匹配到父組件中具有相同值的具有slot屬性的元素
仍然可以有匿名的插槽,它會作為默認(rèn)插槽存在,在插槽找不到匹配的slot值或不具有name的插槽會被插入到匿名的插槽中
<body>
<div id="box">
<h2>具名插槽</h2>
<child>
<h4 slot="header">{{parentMsg}}</h4>
<p>Test</p>
<div>
<p>1.父組件數(shù)據(jù)</p>
<p>2.展示slot使用方法</p>
</div>
<h6 slot="footer">parentFooter</h6>
</child>
</div>
<template id="childTem">
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
<script>
new Vue({
data: {
parentMsg: 'parentHeader'
},
components: {
'child': {
template: '#childTem'
}
}
}).$mount('#box')
</script>
</body>
作用域插槽
+2.1.0新增
作用域插槽是一種特殊類型的插槽,可以用來將子組件的數(shù)據(jù)展示到slot插槽中
在子組件中,只需要將數(shù)據(jù)傳遞到插槽,就像我們將props傳遞給組件一樣,格式為
<slot :text="變量值"></slot>
<!--text是我們自定義的變量名,:表示是動態(tài)的,變量值為我們要從子組件中傳遞的數(shù)據(jù)-->
在父級中,具有特殊屬性的的scope的template元素必須存在,表示這是作用域插槽的模板,scope的值對應(yīng)一個臨時變量名,此變量接收從子組件中傳遞的props對象,格式為:
<child>
<template slot-scope="props">
<!--props是我們自定義的名稱-->
<span>{{props}}</span>
<!--props會接收所有的slot上傳遞的變量值,并將其合成為一個對象,如上面的例子,打印props會得到
{text:變量值}
-->
</template>
</child>
在2.5.0之后的版本官方用slot-scope替換了scope
<body>
<div id="box">
<child>
<template slot-scope="props" slot="test">
<li>{{props.item.name}}</li>
<li>{{props.item.age}}</li>
</template>
</child>
</div>
<template id="childTem">
<ul>
<slot
name="test"
v-for="item in items"
:item="item"
></slot>
</ul>
</template>
<script>
new Vue({
components: {
"child": {
template: "#childTem",
data() {
return {
items: [
{
name: 'xm',
age: 18
}
]
}
}
}
}
}).$mount("#box")
</script>
</body>
這種用法在我們使用Element時非常常見,例如在使用表格組件時需要根據(jù)后臺返回的1、2、3展示對應(yīng)狀態(tài)已完成、未完成、已駁回
<el-table-column
label="狀態(tài)"
minWidth="150">
<template slot-scope="scope">
<span v-if="scope.row.state==1">已完成</span>
<span v-else-if="scope.row.state==2">未完成</span>
<span v-else @click="turn" class="turn">已駁回</span>
</template>
</el-table-column>
在使用slot-scope時,支持es 6 的對象解構(gòu)語法,例如上面的例子,我們可以改寫為
<el-table-column
label="狀態(tài)"
minWidth="150">
<template slot-scope="{row}">
<span v-if="row.state==1">已完成</span>
<span v-else-if="row.state==2">未完成</span>
<span v-else @click="turn" class="turn">已駁回</span>
</template>
</el-table-column>