views/03_UseSlot.vue - 组件插槽使用
案例:折叠面板
![](../assets/mm.gif)
我是内容
寒雨连江夜入吴,
平明送客楚山孤。
洛阳亲友如相问,
一片冰心在玉壶。
总结: 组件内容分发技术, slot占位, 使用组件时传入替换slot位置的标签
1.4 组件进阶 - 插槽默认内容
目标: 如果外面不给传, 想给个默认显示内容
口诀: 夹着内容默认显示内容, 如果不给插槽slot传东西, 则使用夹着的内容在原地显示
默认内容
1.5 组件进阶 - 具名插槽
目标: 当一个组件内有2处以上需要外部传入标签的地方
传入的标签可以分别派发给不同的slot位置
要求: v-slot一般用跟template标签使用 (template是html5新出标签内容模板元素, 不会渲染到页面上, 一般被vue解析内部标签)
components/04/Pannel.vue - 留下具名slot
<span class=“btn” @click=“isShow = !isShow”>
{{ isShow ? “收起” : “展开” }}
views/04_UseSlot.vue使用
案例:折叠面板
芙蓉楼送辛渐
![](../assets/mm.gif)
我是内容
<template #title>
我是标题
<template #content>
寒雨连江夜入吴,
平明送客楚山孤。
洛阳亲友如相问,
一片冰心在玉壶。
v-slot可以简化成#使用
v-bind可以省略成: v-on: 可以省略成@ 那么v-slot: 可以简化成#
总结: slot的name属性起插槽名, 使用组件时, template配合#插槽名传入具体标签
1.6 组件进阶 - 作用域插槽
目标: 子组件里值, 在给插槽赋值时在父组件环境下使用
复习: 插槽内slot中显示默认内容
例子: 默认内容在子组件中, 但是父亲在给插槽传值, 想要改变插槽显示的默认内容
口诀:
-
子组件, 在slot上绑定属性和子组件内的值
-
使用组件, 传入自定义标签, 用template和v-slot=“自定义变量名”
-
scope变量名自动绑定slot上所有属性和值
components/05/Pannel.vue - 定义组件, 和具名插槽, 给slot绑定属性和值
芙蓉楼送辛渐
<span class=“btn” @click=“isShow = !isShow”>
{{ isShow ? “收起” : “展开” }}
{{ defaultObj.defaultOne }}
views/05_UseSlot.vue
案例:折叠面板
{{ scope.row.defaultTwo }}
总结: 组件内变量绑定在slot上, 然后使用组件v-slot=“变量” 变量上就会绑定slot身上属性和值
1.7 组件进阶 - 作用域插槽使用场景
目标: 了解作用域插槽使用场景, 自定义组件内标签+内容
案例: 封装一个表格组件, 在表格组件内循环产生单元格
准备MyTable.vue组件 – 内置表格, 传入数组循环铺设页面, 把对象每个内容显示在单元格里
准备UseTable.vue – 准备数据传入给MyTable.vue使用
components/06/MyTable.vue - 模板(直接复制)
views/06_UseTable.vue - 准备数据, 传入给MyTable.vue组件里循环使用
list: [
{
name: “小传同学”,
age: 18,
headImgUrl:
“http://yun.itheima.com/Upload/./Images/20210303/603f2d2153241.jpg”,
},
{
name: “小黑同学”,
age: 25,
headImgUrl:
“http://yun.itheima.com/Upload/./Images/20210304/6040b101a18ef.jpg”,
},
{
name: “智慧同学”,
age: 21,
headImgUrl:
“http://yun.itheima.com/Upload/./Images/20210302/603e0142e535f.jpg”,
},
],
例子: 我想要给td内显示图片, 需要传入自定义的img标签
正确做法:
在MyTable.vue的td中准备占位, 但是外面需要把图片地址赋予给src属性,所以在slot上把obj数据绑定
components/06/MyTable.vue - 正确代码
{{ obj.headImgUrl}}
在UseTable使用MyTable的时候, template上v-slot绑定变量, 传入img组件设置图片地址
{{ scope.row.headImgUrl }}
总结: 插槽可以自定义标签, 作用域插槽可以把组件内的值取出来自定义内容
除了核心功能默认内置的指令 (v-model
和 v-show
),Vue 也允许注册自定义指令。 v-xxx
html+css的复用的主要形式是组件
你需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令
2.0 自定义指令-注册
目标: 获取标签, 扩展额外的功能
局部注册和使用
07_UseDirective.vue - 只能在当前组件.vue文件中使用
全局注册
在main.js用 Vue.directive()方法来进行注册, 以后随便哪个.vue文件里都可以直接用v-fofo指令
// 全局指令 - 到处"直接"使用
Vue.directive(“gfocus”, {
inserted(el) {
el.focus() // 触发标签的事件方法
}
})
总结: 全局注册自定义指令, 哪里都能用, 局部注册, 只能在当前vue文件里用
2.1 自定义指令-传值
目标: 使用自定义指令, 传入一个值
需求: 定义color指令-传入一个颜色, 给标签设置文字颜色
main.js定义处修改一下
// 目标: 自定义指令传值
Vue.directive(‘color’, {
inserted(el, binding) {
el.style.color = binding.value
},
update(el, binding) {
el.style.color = binding.value
}
})
Direct.vue处更改一下
总结: v-xxx, 自定义指令, 获取原生DOM, 自定义操作
完成如下案例和各步功能
知识点:
-
组件封装
-
动态组件
-
keep-alive
-
作用域插槽
-
自定义指令
3.0 案例-tabbar-初始化项目
目标: 创建项目文件夹, 引入字体图标, 下载bootstrap, less, less-loader@5.0.0 axios, 在App.vue注册组件
- 需求: 从0新建项目, 拆分组件, 创建使用
组件分析:
-
组件拆分:
-
MyHeader.vue – 复用之前的
-
MyTabBar.vue – 底部导航
-
MyTable.vue – 封装表格
-
三个页面
-
-MyGoodsList.vue – 商品页
-
MyGoodsSearch.vue – 搜索页
-
-MyUserInfo.vue – 用户信息页
思路分析:
①: vue create tabbar-demo
②: yarn add less less-loader@5.0.0 -D
③: yarn add bootstrap axios 并在main.js 引入和全局属性
④: 根据需求-创建需要的页面组件
⑤: 把昨天购物车案例-封装的MyHeader.vue文件复制过来复用
⑥: 从App.vue – 引入组织相关标签
新建工程:
vue create tabbar-demo
yarn add less less-loader@5.0.0 -D
yarn add bootstrap axios
在main.js中引入bootStrap.css和字体图标样式
import “bootstrap/dist/css/bootstrap.css”
import “./assets/fonts/iconfont.css”
创建/复制如下文件
从昨天案例中-直接复制过来components/MyHeader.vue
components/MyTabBar.vue
views/MyGoodsList.vue
views/MyGoodsSearch.vue
views/MyUserInfo.vue
components/MyTable.vue
3.1 案例-tabbar-底部封装
目标: 实现MyTabBar.vue组件
- 需求: 把底部导航也灵活封装起来
分析:
①: 基本标签+样式(md里复制)
②: 为tabbar组件指定数据源
③: 数据源最少2个, 最多5个(validator)
④: 从App.vue给MyTabBar.vue传入底部导航的数据
⑤: MyTabBar.vue中循环展示
App.vue-数组准备
tabList: [
{
iconText: “icon-shangpinliebiao”,
text: “商品列表”,
componentName: “MyGoodsList”
},
{
iconText: “icon-sousuo”,
text: “商品搜索”,
componentName: “MyGoodsSearch”
},
{
iconText: “icon-user”,
text: “我的信息”,
componentName: “MyUserInfo”
}
]
MyTabBar.vue - 标签模板
MyTabBar.vue正确代码(不可复制)
class=“tab-item”
v-for=“(obj, index) in arr”
:key=“index”
{{ obj.text }}
不要忘了把tabList数组从App.vue -> MyTabBar.vue
3.2 案例-tabbar-底部高亮
目标: 点击底部导航实现高亮效果
- 需求: 点击底部实现高亮效果
分析:
①: 绑定点击事件, 获取点击的索引
②: 循环的标签设置动态class, 遍历的索引, 和点击保存的索引比较, 相同则高亮
效果演示:
MyTabBar.vue(正确代码)
v-for=“(obj, index) in arr”
:key=“index”
:class=“{current: activeIndex === index}”
@click=“activeIndex = index”>
{{ obj.text }}
3.3 案例-tabbar-组件切换
目的: 点击底部导航, 切换页面组件显示
需求: 点击底部切换组件
分析:
①: 底部导航传出动态组件名字符串到App.vue
②: 切换动态组件is属性的值为要显示的组件名
效果演示:
补充: 给内容div.app- 设置上下内边距
App.vue - 引入并注册
<MyHeader
:background=“‘blue’”
:fontColor=“‘white’”
title=“TabBar案例”
<MyTabBar :arr=“tabList”
@changeCom=“changeComFn”
MyTabBar.vue - 点击传递过来组件名
methods: {
btn(index, theObj) {
this.selIndex = index; // 点谁, 就把谁的索引值保存起来
this.$emit(“changeCom”, theObj.componentName); // 要切换的组件名传App.vue
},
},
3.4 案例-tabbar-商品列表
目标: 为MyGoodsList页面, 准备表格组件MyTable.vue-铺设展示数据
- 需求: 商品列表铺设页面
分析:
①: 封装MyTable.vue – 准备标签和样式
②: axios在MyGoodsList.vue请求数据回来
③: 请求地址: https://www.escook.cn/api/goods
④: 传入MyTable.vue中循环数据显示
⑤: 给删除按钮添加bootstrap的样式: btn btn-danger btn-sm
效果演示:
MyTable.vue - 准备table整个表格标签和样式(可复制)
使用axios请求数据, 把表格页面铺设出来
main.js - 注册axios配置默认地址
import axios from “axios”;
axios.defaults.baseURL = “https://www.escook.cn”;
MyGoodsList.vue - 使用axios请求数据, 把数据传入给MyTable.vue里循环铺设
MyTable.vue里正确代码(不可复制)
:key=“obj.id”
{{ obj.id }} {{ obj.goods_name }} {{ obj.goods_price }} {{ obj.tags }}删除
3.5_案例-tabbar-商品表格-插槽
目标: 使用插槽技术, 和作用域插槽技术, 给MyTable.vue组件, 自定义列标题, 自定义表格内容
- 需求: 允许用户自定义表格头和表格单元格内容
分析:
①: 把MyTable.vue里准备slot
②: 使用MyTable组件时传入具体标签
步骤:
-
提高组件复用性和灵活性, 把表格列标题thead部分预留标签, 设置name属性
-
使用MyTable.vue时, 传入列标题标签
-
表格内容td部分也可以让组件使用者自定义, 也给tbody下tr内留好标签和name属性名
-
使用插槽需要用到插槽内的obj对象上的数据, 使用作用域插槽技术
MyTable.vue - 留好具名插槽