Vue.js 学习笔记九:组件化开发之插槽 slot

目录

插槽 slot

插槽基本使用

具名插槽

作用域插槽

 


插槽 slot

Vue 实现了一套内容分发的 API,将<slot>元素作为承载分发内容的出口。这个自定义的<slot>元素,可以让我们向一个组件传递自定义的内容。

 

插槽基本使用

在子组件中,使用特殊的元素<slot>就可以为子组件开启一个插槽。

该插槽插入什么内容取决于父组件如何使用。

我们可以看一个简单的例子:

		<div id="app">
            <!-- 默认内容 -->
			<my-component></my-component>
			<!-- 按钮替换内容 -->	
			<my-component><button type="button">按钮</button></my-component>		
		</div>
		<template id="my-component">
			<div>
				<h1>我是组件标题</h1>
				<p>我是组件内容</p>
				<slot><p>我是 slot 默认内容</p></slot>
			</div>
		</template>
		<script type="text/javascript">
			 Vue.component('my-component', {
				template: '#my-component'
			}) 
			const app = new Vue({
				el: '#app'
			})
		</script>

<slot> 中的内容表示,如果没有在该组件中插入任何其他内容,就默认显示该内容。 给该组件添加内容,添加的内容会替换<slot></slot>

 

具名插槽

自 2.6.0 起有所更新。 slot attribute 已废弃,官方推荐我们使用 v-slot 来替代。

当子组件的功能复杂时,子组件的插槽可能并非是一个。比如我们封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边。对于这样的情况,<slot> 元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽:

·		<div id="app">
			<my-nav-bar></my-nav-bar>
			<my-nav-bar>
				<a slot="left">返回</a>
				<input slot="center" type="text" value="" placeholder="search ..."/>
				<button slot="right" type="button">查询</button>
			</my-nav-bar>
		</div>
		<template id="my-nav-bar">
			<div>
				<slot name="left"><span>左边</span></slot>
				<slot name="center"><span>中间</span></slot>
				<slot name="right"><span>右边</span></slot>
			</div>
		</template>
		<script type="text/javascript">
			 Vue.component('my-nav-bar', {
				template: '#my-nav-bar'
			}) 
			const app = new Vue({
				el: '#app'
			})
		</script>

在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:

		<div id="app">
			<my-nav-bar>
				<template v-slot:left>
					<a>返回</a>
				</template>
				<template v-slot:center>
					<input type="text" value="" placeholder="search ..."/>
				</template>
				<template v-slot:right>
					<button type="button">查询</button>
				</template>
			</my-nav-bar>
		</div>

注意: v-slot只能添加在一个<template>上,只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。

v-slot也有语法糖,即把参数之前的所有内容 v-slot: 替换为字符#

		<div id="app">
			<my-nav-bar>
				<template #left>
					<a>返回</a>
				</template>
				<template #center>
					<input type="text" value="" placeholder="search ..."/>
				</template>
				<template #right>
					<button type="button">查询</button>
				</template>
			</my-nav-bar>
		</div>

 

作用域插槽

自 2.6.0 起有所更新。 slot-scope attribute 已废弃,官方推荐我们使用 v-slot 来替代。

作用域插槽是 slot 一个比较难理解的点,而且官方文档说的又有点不清晰。

这里,我们用一句话对其做一个总结:父组件替换插槽的标签,但是内容数据由子组件来提供。

例如,子组件中包括一组数据,比如languages : ['Java', 'JavaScript', 'Python', 'Go']:

		<div id="app">
			<my-component></my-component>
		</div>
		<template id="my-component">
			<div>
				<slot>
                    <div v-for="lang in languages"> {{ lang }}</div>
                </slot>			
			</div>
		</template>
		<script type="text/javascript">
			 Vue.component('my-component', {
				template: '#my-component',
				data() {
					return {
						languages : ['Java', 'JavaScript', 'Python', 'Go']
					}
				}
			})
			const app = new Vue({
				el: '#app'
			})
		</script>

需要在多个界面进行展示:某些界面是以水平方向一一展示的,某些界面是以列表形式展示的,某些界面直接展示一个数组。

这时利用 slot 作用域插槽就可以了。

		<div id="app">
            <my-component></my-component>
			<my-component>
				<template slot-scope="data">
					<div>{{ data.data.join(' ') }}</div>
				</template>
			</my-component>
		</div>
		<template id="my-component">
			<div>
				<slot :data="languages">
					<div v-for="lang in languages"> {{ lang }}</div>
				</slot>				
			</div>
		</template>

在父组件使用我们的子组件时,从子组件中拿到数据:我们通过 <template slot-scope="data"> 获取到data 属性,再通过data.data 就可以获取到刚才我们传入的data了。

绑定在 <slot> 元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:

                <template v-slot="data">
					<div>{{ data.data.join(' ') }}</div>
				</template>

一个不带 name<slot> 出口会带有隐含的名字default:

				<template v-slot:default="data">
					<div>{{ data.data.join(' ') }}</div>
				</template>
				<!-- 缩写 -->
				<template #default="data">
					<div>{{ data.data.join(' ') }}</div>
				</template>

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stary1993

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值