slot 是Vue中的一个概念。把父组件中的内容插入到子组件中。有3种类型的slot, 下面分别详细描述其用法
1. 单个插槽
又称为默认插槽,匿名插槽。是最简单的一种形式。用法如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue slot demo</title>
</head>
<body>
<script src="./vue.js"></script>
<div id="app">
<child-comp>
<div>hello</div>
</child-comp>
</div>
<script>
Vue.component('child-comp', {
template: `<div><slot></slot></div>`
})
const app = new Vue({
el: '#app'
})
</script>
</body>
</html>
定义了一个子组件child-comp, 在子组件中写上<slot></slot>,那么父组件中的内容就会插入到这里。我们看一下模板渲染出的渲染函数长什么样:
父组件渲染函数:
function anonymous(
) {
with(this){return _c('div',{attrs:{"id":"app"}},[_c('child-comp',[_c('div',[_v("hello")])])],1)}
}
子组件渲染函数:
function anonymous(
) {
with(this){return _c('div',[_t("default")],2)}
}
从子组件渲染函数中看出<slot></slot>渲染成了_t("default"), 其实默认插槽的名字叫default。
2. 具名插槽
顾名思义这种插槽有名字,用法如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue slot demo</title>
</head>
<body>
<script src="./vue.js"></script>
<div id="app">
<child-comp>
<div slot="liu">hello</div>
</child-comp>
</div>
<script>
Vue.component('child-comp', {
template: `<div><slot name="liu"></slot></div>`
})
const app = new Vue({
el: '#app'
})
</script>
</body>
</html>
具名插槽要在子组件中写上 name="liu",在父组件中写上slot="liu" ,如果父组件中写的名字和子组件定义的名字不一致就渲染不出来父组件中的内容。因为通过名字找不到要插入的地方。我们看看具名插槽的渲染函数:
父组件渲染函数:
function anonymous(
) {
with(this){return _c('div',{attrs:{"id":"app"}},[_c('child-comp',[_c('div',{attrs:{"slot":"liu"},slot:"liu"},[_v("hello")])])],1)}
}
子组件渲染函数:
function anonymous(
) {
with(this){return _c('div',[_t("liu")],2)}
}
对比一下匿名插槽,具名插槽子组件渲染函数和匿名插槽只是名字改变了,由default 变为自己定义的名字liu。具名插槽父组件增加了一个对象,这个对象有attrs和slot属性
{
attrs:{
"slot":"liu"
},
slot:"liu"
}
3. 作用域插槽
这个插槽可以把子组件中的参数传递个父组件中。用法如下:
<html>
<head>
<meta charset="utf-8">
<title>vue slot demo</title>
</head>
<body>
<script src="./vue.js"></script>
<div id="app">
<child-comp>
<div slot="liu" slot-scope="item">{{item.params}}</div>
</child-comp>
</div>
<script>
Vue.component('child-comp', {
template: `<div><slot name="liu" :params="'hello'"></slot></div>`
})
const app = new Vue({
el: '#app'
})
</script>
</body>
</html>
作用域插槽要在子组件中绑定一个参数,在父组件中定义slot-scope="item", 通过slot-scope可以把子组件中绑定的参数取出来。渲染函数就比较复杂了,大体看一下吧
父组件渲染函数:
unction anonymous(
) {
with(this){return _c('div',{attrs:{"id":"app"}},[_c('child-comp',{scopedSlots:_u([{key:"liu",fn:function(item){return _c('div',{},[_v(_s(item.params))])}}])})],1)}
}
子组件渲染函数:
unction anonymous(
) {
with(this){return _c('div',[_t("liu",null,{"params":'hello'})],2)}
}
这个作用域插槽还是个具名插槽。匿名插槽也可以传递参数,把名字去掉就可以了。如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue slot demo</title>
</head>
<body>
<script src="./vue.js"></script>
<div id="app">
<child-comp>
<div slot-scope="item">{{item.params}}</div>
</child-comp>
</div>
<script>
Vue.component('child-comp', {
template: `<div><slot :params="'hello'"></slot></div>`
})
const app = new Vue({
el: '#app'
})
</script>
</body>
</html>