组件插槽 slot
1.作用
父组件向子组件传递内容(这里的内容指模板,而并非数据)
2.示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<!--添加的值替换了默认插槽的内容-->
<!--信息通过插槽的数据动态改变-->
<my-slot>出现BUG</my-slot>
<my-slot>出现警告</my-slot>
<my-slot></my-slot>
</div>
<script type="text/javascript" src="../../js/vue.js"></script>
<script type="text/javascript">
/*
组件插槽:父组件向子组件传递内容
*/
Vue.component('my-slot', {
// 模拟一个提示功能
// 第一个数据为 ERROR,有提示作用
// 第二个参数需要根据业务动态改变,因此采用插槽 slot
template: `
<div>
<strong>插槽标签:</strong>
<slot>插槽内容</slot>
</div>
`
});
let vm = new Vue({
el: '#app',
data: {}
});
</script>
</body>
</html>
3.具名插槽 ===> 有名字的插槽
(1)插槽定义
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
(2)插槽使用
<base-layout>
<h1 slot="header">标题内容</h1>
<p>主要内容1</p>
<p>主要内容2</p>
<p slot="footer">底部内容</p>
</base-layout>
(3)示例代码1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<my-layout>
<!--将 插槽名为 header 的插槽内容填充为 标题信息 -->
<p slot='header'>标题信息</p>
<p>正文内容</p>
<p slot='footer'>底部信息信息</p>
</my-layout>
</div>
<script type="text/javascript" src="../../js/vue.js"></script>
<script type="text/javascript">
/*
具名插槽
*/
Vue.component('my-layout', {
template: `
<div>
<header>
<slot name='header'></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name='footer'></slot>
</footer>
</div>
`
});
let vm = new Vue({
el: '#app',
data: {
}
});
</script>
</body>
</html>
(4)示例代码2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<my-layout>
<!--template的作用为临时性的包裹信息,而不会产生新的 html标签-->
<template slot='header'>
<p>章标题</p>
<p>节标题</p>
</template>
<p>第一部分内容</p>
<p>第二部分内容</p>
<template slot='footer'>
<p>底部页码</p>
<p>底部页脚</p>
</template>
</my-layout>
</div>
<script type="text/javascript" src="../../js/vue.js"></script>
<script type="text/javascript">
/*
具名插槽
*/
Vue.component('my-layout', {
template: `
<div>
<header>
<slot name='header'></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name='footer'></slot>
</footer>
</div>
`
});
let vm = new Vue({
el: '#app',
data: {
}
});
</script>
</body>
</html>
4.作用域插槽
应用场景: 父组件对子组件的内容进行加工处理
(1)定义与使用方法
<ul>
<li v-for="item in list" v-bind:key="item.id">
<!--子组件利用 v-bind 绑定一个自定义名称,该自定义名称后面的 item 为上面遍历出来的单一元素-->
<slot v-bind:item="item">
{{item.name}}
</slot>
</li>
</ul>
<my-list v-bind:list="list">
<!--父组件可以利用 slot-scope 标签得到子组件中绑定的属性,即上面的 key 属性-->
<template slot-scope="slotProps">
<strong v-if="slotProps.item.current">
{{ slotProps.item.text }}
</strong>
</template>
</my-list>
(2)示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style type="text/css">
.current {
color: red;
}
</style>
<body>
<div id="app">
<!--父组件给子组件传递fruit_list_data数据-->
<fruit-list v-bind:list='fruit_list_data'>
<!--slot-scope 属性用于得到被 v-bind 绑定的属性值,其中参数my_slot_data为自定义名称-->
<template slot-scope='my_slot_data'>
<!--将 id 为 3 的数据指定样式类为 current 类 -->
<!--利用 if else 语句将 id 为 3 的水果名字高亮 -->
<strong v-if='my_slot_data.info.id === 3' class="current">{{my_slot_data.info.name}}</strong>
<!--其他水果名字正常显示 -->
<span v-else>{{my_slot_data.info.name}}</span>
</template>
</fruit-list>
</div>
<script type="text/javascript" src="../../js/vue.js"></script>
<script type="text/javascript">
/*
作用域插槽
*/
Vue.component('fruit-list', {
props: ['list'],
template: `
<div>
<li :key='item.id' v-for='item in list'>
<slot v-bind:info='item'>{{item.name}}</slot>
</li>
</div>
`
});
let vm = new Vue({
el: '#app',
data: {
fruit_list_data: [{
id: 1,
name: '苹果'
},{
id: 2,
name: '橙子'
},{
id: 3,
name: '香蕉'
},{
id: 4,
name: '西瓜'
}]
}
});
</script>
</body>
</html>