简介
开发中页面里经常看到【结构相似】的组件,在vue中定义组件时就可以通过其插槽特性,替换组件中的组成部分达到灵活配置的目的。
后备内容
<body>
<div id="content">
<my-com></my-com>
</div>
</body>
<script>
Vue.component('my-com', {
template: `
<div>
<slot>默认值</slot>
</div>
`
});
var vm = new Vue({
el: '#content',
data: {}
});
</script>
运行,如果模板中不输入东西(包括按一堆空格,但不包括 )就会使用后备内容,如果输入将会取代后备内容。
具名插槽
如果一个组件中需要定义多个插槽,可以在模板中通过定义具名插槽,再在html的组件中用替换内容。
<body>
<div id="content">
<my-com>
<!-- 插入头部插槽内容 -->
<template v-slot:header>
<h1>header</h1>
</template>
<!-- 插入默认插槽内容 -->
<p>main</p>
<!-- 插入底部插槽内容 -->
<template v-slot:footer>
<h2>footer</h2>
</template>
</my-com>
</div>
</body>
<script>
Vue.component('my-com', {
template: `
<div>
<!-- 定义头部插槽位置 -->
<slot name="header"></slot>
<!-- 定义默认插槽位置 -->
<slot></slot>
<!-- 定义底部插槽位置 -->
<slot name="footer"></slot>
</div>
`
});
var vm = new Vue({
el: '#content',
data: {}
});
</script>
运行:
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header:
<my-com>
<!-- 插入头部插槽简写 -->
<template #header>
<h1>header</h1>
</template>
<!-- 插入头部插槽 -->
<p>main</p>
<!-- 插入头部插槽简写 -->
<template #footer>
<h2>footer</h2>
</template>
</my-com>
作用域插槽
假设我们在插槽中使用了组件data中的属性,如果在html使用插槽时也要用组件的data,就需要作用域插槽。
<body>
<div id="content">
<my-com>
<template>
{{obj.name}}
</template>
</my-com>
</div>
</body>
<script>
Vue.component('my-com', {
data() {
return {
obj: {
"name": "tom",
"defalut": "nobody"
}
}
},
template: `
<div>
<slot>
{{obj.defalut}}
</slot>
</div>
`
});
var vm = new Vue({
el: '#content',
});
</script>
运行发现在html的自定义组件标签的插槽中无法直接使用到子组件的data:
需要在组件的中bind组件data的属性v-bind:xxx=“data中的属性”,然后在html引用组件使用插槽时在插槽声明子组件作用域,最后就能按【作用域名.xxx】访问子组件data:
<body>
<div id="content">
<my-com>
<template v-slot="sonScope">
{{sonScope.xxx.name}}
</template>
</my-com>
</div>
</body>
<script>
Vue.component('my-com', {
data() {
return {
obj: {
"name": "tom",
"defalut": "nobody"
}
}
},
template: `
<div>
<slot v-bind:xxx="obj">
{{obj.defalut}}
</slot>
</div>
`
});
var vm = new Vue({
el: '#content',
});
</script>
运行,此时在html使用插槽时可以访问组件中data: