vue2.X基础知识六之slot内容分发

8 篇文章 0 订阅

    当需要让组件组合使用,混合父组件的内容与子组件的模板时,就会用到slot,这个过程叫做内容分发。

1、slot内容分发

在子组件内使用特殊的<slot>元素就可以为这个子组件开启一个slot(插槽),在父组件模板里,插入在子组件标签内的所有内容将替代子组件的<slot>标签及它的内容。例如:

<div id="app">
    <child-component>
	<div>分发的内容</div>
	<p>更多分发的内容</p>
    </child-component>
    <!-- 子组件里没有内容时,显示slot里面的内容 -->
    <child-component></child-component>
</div>
<script>
			
    /* slot 当子组件没有内容的时候显示(备用内容) */
    Vue.component('child-component',{
	template: '<div>\
	               <slot>如果父组件里的子组件标签里没有插入内容,我将作为默认出现</slot>\
		   </div>',
		   data: function(){
		   	    return {
			        name: '子组件的数据;'
			    }
			}
			});
			
    var app = new Vue({
        el: '#app'
    });
</script>

没有name属性的slot将作为默认slot出现,父组件没有使用slot特性的元素与内容都将出现在这里;如果没有指定默认的匿名slot,父组件内多余的内容片段都将被抛弃。例如:

               <div id="app">
			<child-component>
				<h2 slot="header">标题</h2>
				<p>正文内容</p>
				<p>更多的正文内容</p>
				<div slot="footer">底部信息</div>
			</child-component>
		</div>
            <script>	
         	Vue.component('child-component',{
				template: `
				<div class="container">
					<div class="header">
						<slot name="header"></slot>
					</div>
					<div class="main">
						<slot></slot>
					</div>
					<div class="footer">
						<slot name="footer"></slot>
					</div>
				</div>
				`
			});
			
			var app = new Vue({
				el: '#app'
			});
            </script>

以上代码中,类名为main的div里面的slot没有name属性,是默认的slot,显示的内容正是子组件child-component里的两个没有slot属性的p标签里面的内容;子组件<slot>内的备用内容,它的作用域是子组件本身。

2、作用域插槽

    作用域插槽是一种特殊的slot,使用一个可以复用的模板替换已渲染元素。例如:

                <div id="app">
			<child-component>
				<!-- 临时变量props,用于访问来自子组件插槽的数据msg -->
				<template slot-scope="props">
					<p>来自父组件的内容</p>
					<p>{{ props.msg }}</p>
				</template>
			</child-component>
		</div>
		<script>
			/*
			 没有name的slot将作为默认slot出现,父组件没有使用slot特性的元素与内容都将
			 出现在这里;如果没有指定默认的匿名slot,父组件内多余的内容片段都将被抛弃
			 * 
			 * */
			Vue.component('child-component',{
				template: `
				<div class="container">
					<slot msg="来自子组件的内容"></slot>
				</div>
				`
			});
			
			var app = new Vue({
				el: '#app'
			});
                </script>

作用域插槽更具代表性的用例是列表组件;允许组件自定义应该如何渲染列表每一项。例如:

                <div id="app">
			<my-list :books="books">
				<!-- 作用域插槽也可以是具名的slot -->
				<template slot="book" slot-scope="props">
					
						<li>{{ props.bookName }}</li>

				</template>
			</my-list>
		</div>
		<script>
			Vue.component('my-list', {
				props: {
					books: {
						type: Array,
						default: function () {
							return [];
						}
					}
				},
				template: `
					<ul>
						<slot name="book" v-for="book in books" :book-name="book.name">
						</slot>
					</ul>
					
				`
			});
			var app = new Vue({
				el: '#app',
				data: {
					books: [
						{name: '《vue.js实战》'},
						{name: '《javascript语言精粹》'},
						{name: '《javascript高级程序设计》'}
					]
				}
			});
		</script>
3、访问slot

    通过$slot可以访问某个具名slot,this.$slots.default包括了所有没有被包含在具名slot中的节点。例如:                   

            <div id="app">
			<child-component>
				<h2 slot="header">标题</h2>
				<p>正文内容</p>
				<p>更多正文内容</p>
				<div slot="footer">底部信息</div>
			</child-component>
		</div>
		<script>
			Vue.component('child-component', {
				template: `
					<div class="container">
						<div class="header">
							<slot name="header"></slot>
						</div>
						<div class="main">
							<slot></slot>
						</div>
						<div class="footer">
							<slot name="footer"></slot>
						</div>
					</div>
				`,
				mounted: function () {
					var header = this.$slots.header;
					var main = this.$slots.default;
					var footer = this.$slots.footer;
					console.log(footer); // 打印出footer元素的虚拟dom对象
					console.log(footer[0].elm.innerHTML); // "底部信息"
				}
			});
			
			var app = new Vue({
				el: '#app'
			});
		</script>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值