Vue实现了一套内容分发的API,将
在总结slot的内容之前,先来看一下编译的作用域的内容。
<div id="app">
<test>
{{message}}
test>
div>
如上代码所示,
父组件模板的内容是在父组件作用域内编译,子组件模板的内容是在子组件作用域内编译:
<div id="app">
<test v-show="show111">test>
div>
<script>
Vue.component('test', {
template: '子组件!'
});
var app = new Vue({
el: "#app",
data:{
show111:false
}
})
script>
上面代码中,show111绑定的是父组件的数据,是在父组件的作用域内编译。如果想绑定在子组件上:
<div id="app">
<test>test>
div>
<script>
Vue.component('test', {
data:function(){
return {
show111:false
}
},
template: '子组件!'
});
var app = new Vue({
el: "#app",
})
script>
而我们接下来要总结的slot的内容,它的作用域是在父组件上的。
在子组件内部使用特殊的
<div id="app">
<test>你好!test>
div>
<script>
Vue.component('test', {
template: ' '
});
var app = new Vue({
el: "#app",
})
script>
在渲染过程中,
渲染结果为:
<div id="app">
<div>你好!div>
div>
还可以设置默认出现的内容:
<div id="app">
<test>test>
div>
<script>
Vue.component('test', {
template: '如果父组件没有插入内容,我将默认出现!
'
});
var app = new Vue({
el: "#app",
})
script>
在父组件模板中没有插入内容,因此
<div id="app">
<div><p>如果父组件没有插入内容,我将默认出现!p>div>
div>
插槽内可以包含代码:
<test><span>你好:span>test>
渲染结果为:
<div id="app">
<div><span>你好:span>div>
div>
如果组件
<div id="app">
<test><span>你好:span>test>
div>
<script>
Vue.component('test', {
template: ''
});
var app = new Vue({
el: "#app",
})
script>
渲染结果为:
<div id="app">
<div>div>
div>
在向具名插槽提供内容的时候,可以在父组件的元素上使用slot属性:
<div id="app">
<test>
<template slot="title">
我是标题!
template>
<template slot="content">
我是内容!
template>
test>
div>
<script>
Vue.component('test', {
template: `
`
});
var app = new Vue({
el: "#app",
})
script>
渲染的结果为:
<div id="app">
<div>
<h3>我是标题!h3>
<div>我是内容!div>
div>
div>
也可以向其中插入代码,并且具名slot可以和单个slot共存:
<div id="app">
<test>
<h1 slot="title">
我是标题!
h1>
<p slot="content">
我是内容!
p>
<div>
我是页脚!
div>
test>
div>
<script>
Vue.component('test', {
template: `
`
});
var app = new Vue({
el: "#app",
})
script>
渲染结果为:
<div id="app">
<div>
<h1>我是标题!h1>
<p>我是内容!p>
<div>我是页脚!div>
div>
div>
<div id="app">
<test>
{{title}}
test>
div>
<script>
Vue.component('test', {
template: `
`
});
var app = new Vue({
el: "#app",
data:{
title:"我是标题!"
}
})
script>
渲染结果为:
<div id="app">
<div>
我是标题!
div>
div>
注意这个插槽不能访问
正常情况下来讲,在插槽中插入的内容只能访问父级作用域的数据。而使用作用域插槽,可以在插槽中访问来自子组件的数据。
<div id="app">
<test>
<template slot-scope="props">
<p>来自父组件!p>
<p>{{props.message1}}p>
<p>{{props.message2}}p>
template>
test>
div>
<script>
Vue.component('test', {
template: `
`
});
var app = new Vue({
el: "#app",
})
script>
渲染结果为:
<div id="app">
<div>
<p>来自父组件!p>
<p>来自子组件!p>
<p>来自子组件!!!p>
div>
div>
在子组件模板的slot上可以传递数据message1=“来自子组件!”, message2=“来自子组件!!!”。在父组件中使用了元素,拥有一个slot-scope="props"特性,这里的props是一个临时的变量,就像v-for="item in items"中的item一样,然后在中就可以通过临时变量props访问来自子组件插槽传递的数据message1和message2。
在 2.5.0+,slot-scope 不再限制在 元素上使用,可以用在插槽内的任何元素或组件上。
可以通过$slots获取被slot分发的内容:
<div id="app">
<test>
<div>
我是页脚!
div>
<h1 slot="header">
我是标题!
h1>
<p slot="content">
我是内容!
p>
test>
div>
<script>
Vue.component('test', {
template: `
`,
mounted:function(){
let header=this.$slots.header;
let content=this.$slots.content;
let footer=this.$slots.default;
console.log(header[0].elm);
console.log(content[0].tag);
console.log(footer);
},
});
let app = new Vue({
el: "#app",
})
script>
参考:
1.Vue.js官方文档
2.《Vue.js实战》