三连多大胆,就有多大产!开源促使进步,献给每一位技术使用者和爱好者!
干货满满,摆好姿势,准备发车
前言
之前的一系列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、哪里的名字是可以自定义的,然后就妥妥的收入技能库了
运行结果
我们将列表数据,替换成一行,使用 - 隔开
总结
- 组件化到此就结束了
- 为什么会有组件化,有什么好处
- 组件化基本使用,模板抽离,数据访问
- 父子组件通信,互相访问
- 插槽、具名插槽和作用于插槽
以上总结就是组件化讲的所有内容了,一定要屁股坐下来多练多思考多交流,方能运用自如,我们都会越来越棒,加油,开始练习吧
还是 欢迎评论区交流,喜欢就三连
一下吧,我们下期见