前言
当父组件在使用一个子组件的时候,可以使用单标签的形式,也可以使用双标签的形式,比如<Child /> 或者<Child></Child>。当时使用双标签的形式时,如果我们在两个标签中放入一些内容,比如<Child>hello world</Child>,子组件是可以通过插槽slot来获取标签中的内容,下面是官网的几个demo
demo1
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<!-- 使用子组件 -->
<navigation-link>这是父组件上的一些内容</navigation-link>
</div>
</body>
</html>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
// 注册子组件navigation-link
Vue.component('navigation-link', {
data() {},
// 如果 <navigation-link> 没有包含一个 <slot> 元素,则任何传入它的内容都会被抛弃。
template: `
<a v-bind:href="url" class="nav-link" >
<slot></slot>
</a>`
})
new Vue({
el: '#app',
data: {
}
})
</script>
demo2-具名插槽
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<base-layout>
<!-- template 也可以是个普通元素,请看footer的slot -->
<template slot="header">
<h1>页面标题</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<div slot="footer">
<mark>页面底部信息</mark>
</div>
</base-layout>
</div>
</body>
</html>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
// slot具名以后就可以插到对应的位置,否则规则跟非具名插槽一样
Vue.component('base-layout', {
template: `
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>`
})
new Vue({
el: '#app'
})
</script>
demo3-默认值
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<Child>提交</Child>
<!--当Child中间不传入内容时使用默认值-->
<Child></Child>
</div>
</body>
</html>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
Vue.component('Child',{
template: `
<button type="submit">
<slot>Submit</slot>
</button>`
});
new Vue({
el: '#app'
})
</script>
demo4-作用域插槽
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<todo-list :todos="todos">
<!-- 用slot-scope接收子组件回传的信息 -->
<template slot-scope="slotProps">
<span v-if="slotProps.todo.isComplete"></span> {{ slotProps.todo.text }}
</template>
</todo-list>
</div>
</body>
</html>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
Vue.component('todo-list', {
props: ['todos'],
template: `
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id">
<!-- 回传信息 -->
<slot v-bind:todo="todo">
{{ todo.text }}
</slot>
</li>
</ul>`
})
new Vue({
el: '#app',
data: {
todos: [
{
text: '买机械键盘',
isComplete: true
}, {
text: '打羽毛球',
isComplete: true
},
{
text: '去教会做礼拜',
isComplete: false
}]
}
})
</script>