【Vue系列7】—— 组件化插槽应用

三连多大胆,就有多大产!开源促使进步,献给每一位技术使用者和爱好者!
干货满满,摆好姿势,准备发车

前言

之前的一系列Vue文章,介绍了Vuede基础语法、组件化、以及父子组件的通信等,这篇文章是组件化的最后一篇,之后我们就要进入 Vue 脚手架(Vue CLI)部分了,希望各位读者朋友记得三连掌握不夜学长的最新动态,谢谢大家阅读支持,也由心希望能够帮助到大家,快乐你我!这篇要打开哪里的大门呢?我们一起往 看吧

插槽

概述

插槽英文是slot,生活中如:电脑的USB插槽、插排上的电源插槽,插槽的目的是让我们原来的设备具备更多的扩展性,比如电脑的USB我们可以插入U盘、硬盘、手机、音响、键盘,插排让我们连接更多设备等。

组件的插槽也是为了让我们封装的组件更加具备扩展性,让使用者可以决定组件内部的一些内容到底展示什么!

例子

比如移动网站中的导航栏,移动端开发中,几乎每个页面都有导航栏,导航栏我们必然会封装成一个组件(这里体现了组件的重用性),比如取名叫 nav-bar,一旦有了这个组件,我们可以在多个页面中重复使用

但是每个页面的导航栏又不尽相同,如下图,三个页面的导航栏各不相同,如果我们把组件写死必然是不行的,我们需要在组件中预料插槽,让其自定义扩展

在这里插入图片描述

如何封装这类组件

这些组件有很多区别,但是也有很多共性,比如每个页面都有相同的返回键,有的页面是菜单按钮,有的中间是搜索框,有的是文字,我们封装成一个不合适,分别封装三个又重复封装了

所以我们要抽取共性(返回键),保留不同(将搜索框/文字/菜单按钮预留出来),最好的方式就是将共性抽取出来封装到组件中,将不同暴露为插槽,一旦我们预留了插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容!

那插槽是什么呢?就是让组件内部决定自己的一些细节应该如何处理的一个技术,提高组件内部的扩展性,让页面不那么死板,我相信到这里,大家一定是理解了插槽的作用,接下来就是如何使用插槽了!

使用插槽

案例

使用插槽默认显示一个按钮,组件可以根据自己的需求将按钮替换成文字或者其他

步骤

  • 使用<slot></slot>设置插槽
  • 使用<slot><button></button></slot>设置插槽并设置插槽内默认值
  • 使用组件时如果写了子标签,插槽内设置的默认值会全部替换

代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			<!-- 使用cpn组件的默认插槽 -->
			<cpn></cpn>
			<!-- 使用组件,将插槽由原来的 按钮1 改为 按钮2 -->
			<cpn>
				<button>按钮2</button>
			</cpn>
			<!-- 将按钮改为 i 标签 -->
			<cpn>
				<i>组件插槽</i>
			</cpn>
		</div>
	</body>
	
	<template id="cpn">
		<div>
			<h2>我是组件</h2>
			<p>我是组件,哈哈哈</p>
			<!-- 
				1、使用slot定义组件
				2、在slot中可以定义默认标签
			-->
			<slot>
				<button type="button">按钮</button>
			</slot>
		</div>
	</template>
	<script type="text/javascript">
		const cpn = {
			template: "#cpn"
		}
		
		const app = new Vue({
			el: "#app",
			components: {
				cpn
			}
		})
	</script>
</html>

截图

一下结果发现,组件的前两行数据都是一样的,按钮部分使用slot标签包裹,分别展示为按钮1(默认),按钮2和i标签
在这里插入图片描述

这里为止,大家再体会一下插槽的特点,不正是可以在具体使用时替换显示内容,增加组建的扩展性吗。这里最好停一下去练一练,基础用法掌握之后,还没有完哦,我们继续探究

具名插槽

上边我们只有一个插槽是吧,我们替换的时候就将那仅仅的一个插槽给替换掉了,如果一个组件模板中定义了多个插槽,我们可以给插槽设置name属性,也就是起个名字,就可以在替换插槽时修改指定的插槽不至于乱套

用法

  • 在slot标签中使用name属性
  • 在替换插槽时在替换的标签内部写slot属性
  • 属性值为要替换的插槽的name属性值

下凡有代码贴出,紧接着有一张对照图,可以参考一下

代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			<cpn>
				<!-- 在标签中使用slot属性对应插槽的name属性值 -->
				<button slot="left">返回</button>
				<input type="text" slot="center"/>
				<span slot="right">...</span>
			</cpn>
		</div>
	</body>
	
	<template id="cpn">
		<div>
			<!-- 使用name属性给slot标签起名字 -->
			<slot name="left">左边</slot>
			<slot name="center">中间</slot>
			<slot name="right">右边</slot>
		</div>
	</template>
	<script type="text/javascript">
		const cpn = {
			template: "#cpn"
		}
		
		const app = new Vue({
			el: "#app",
			components: {
				cpn
			}
		})
	</script>
</html>

对照参考图
在这里插入图片描述

截图

这样左侧,中间和右侧内容都对应的做出了替换,那么读者朋友们,能不能自己实现一个电商手机端的首页头部部分呢?别走开,看完再试哈哈,有问题的话咱们下方评论区交流,写出来的评论区记得分享一下。
在这里插入图片描述

这里我们还要说最后一个知识点,看累的读者朋友们可以喝杯茶休息休息,要说的就是作用于插槽,在此之前我们先熟悉一个编译作用域的概念,跟着学长的思路往下走吧

编译作用域

如果在Vue实例中使用data中数据则会使用Vue实例中的数据,如果在template中使用数据则使用组件的data数据。
父组件模板中的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域编译,这就是所说的编译作用域

案例

  • 我们定义了父子组件
  • 父子组件中分别有isShow变量一个,值为true和false

代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			<cpn v-show="isShow"></cpn>
		</div>
	</body>
	<template id="cpn">
		<div v-show="isShow">
			<h2>我是标题</h2>
			<p>我是段落</p>
		</div>
	</template>
	<script type="text/javascript">
		const cpn = {
			template: "#cpn",
			data() {
				return {
					isShow: false
				}
			}
		}
		
		const app = new Vue({
			el: "#app",
			data: {
				isShow: true
			},
			components: {
				cpn
			}
		})
	</script>
</html>

图解

在这里插入图片描述

通过上边的代码和图解大家需要知道的是,在组件模板中变量使用自己的,一旦件组件运用到父组件中,变量就会使用父组件的了,这就引出了下边的作用域插槽,我们往下走一探究竟

作用域插槽

概述

在父组件中我们使用子组件时,发现子组件中展示数据的方式并不是自己想要的,想要以自己的形式展示数据,但是又不能直接获取到数据,我们可以使用作用域插槽,实现父组件替换插槽标签,但是内容由子组件提供

案例

这里使用文字先说一下,下方学长配有代码和图例(贴心),如有不懂评论区见

  • 案例的需求就是数据在子组件中声明,使用插槽替换标签,要求显示子组件数据
  • 创建子组件,并在data中创建数据
  • 在template中创建子组件模板,在slot标签中使用**:data属性(该名字可自定义)子组件data**变量名保持一致
  • 在父组件中使用子组件模板,通过template标签 使用slot-scope 属性,属性值可以自定义,暂定为 slot
  • 在标签内不使用数据时,使用 slot.data的方式使用数据,大家记得slot和data的名字是可以自定义的

代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			<!-- 我们这里使用cpn则发现使用多次每次展示的形式都是ul列表 -->
			<cpn></cpn>
			<cpn>
				<!-- 使用slot-scope属性(属性值可自定义)定义slot作用域 -->
				<template slot-scope="slot">
					<!-- 使用数据,slot和data一一对应即可 -->
					<span>{{slot.data.join(' - ')}}</span>
				</template>
			</cpn>
		</div>
	</body>
	<template id="cpn">
		<div>
			<!-- 定义:data属性(改属性可自定义)绑定数据 -->
			<slot :data="pLanguages">
				<ul>
					<li v-for="item in pLanguages">{{ item }}</li>
				</ul>
			</slot>
		</div>
	</template>
	<script type="text/javascript">
		const cpn = {
			template: "#cpn",
			data() {
				return {
					pLanguages: ['Java','Python','Scala','Go','Java Script']
				}
			}
		}
		
		const app = new Vue({
			el: "#app",
			components: {
				cpn
			}
		})
	</script>
</html>

图解

这里要掌握的是哪里 1、需要对应起来,2、哪里的名字是可以自定义的,然后就妥妥的收入技能库了
在这里插入图片描述

运行结果

我们将列表数据,替换成一行,使用 - 隔开
在这里插入图片描述

总结

  • 组件化到此就结束了
  • 为什么会有组件化,有什么好处
  • 组件化基本使用,模板抽离,数据访问
  • 父子组件通信,互相访问
  • 插槽、具名插槽和作用于插槽

以上总结就是组件化讲的所有内容了,一定要屁股坐下来多练多思考多交流,方能运用自如,我们都会越来越棒,加油,开始练习吧
还是 欢迎评论区交流,喜欢就三连一下吧,我们下期见

我是不夜学长,乐于分享,我们一起加油吧!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

石添的编程哲学

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值