{
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 - 留好具名插槽
:key=“obj.id”
MyGoodsList.vue 使用
<template #header>
# 商品名称 价格 标签 操作<template #body=“scope”>
{{ scope.row.id }} {{ scope.row.goods_name }} {{ scope.row.goods_price }}{{ scope.row.tags }}
<button class=“btn btn-danger btn-sm”
删除
3.6 案例-tabbar-商品表格-tags微标
目标: 把单元格里的标签, tags徽章铺设下
- 需求: 标签列自定义显示
分析:
①: 插槽里传入的td单元格
②: 自定义span标签的循环展示-给予样式
效果演示:
bootstrap徽章: https://v4.bootcss.com/docs/components/badge/
MyGoodsList.vue - 插槽
<span v-for=“(str, ind) in scope.row.tags” :key=“ind”
class=“badge badge-warning”
{{ str }}
下面额外添加样式
3.7 案例-tabbar-商品表格-删除功能
目标: 点击删除对应这条数据
- 需求: 点击删除按钮删除数据
分析:
①: 删除按钮绑定点击事件
②: 作用域插槽绑定id值出来
③: 传给删除方法, 删除MyGoodsList.vue里数组里数据
效果演示
提示: id在MyTable.vue里, 但是MyGoodsList.vue里要使用, 而且在插槽位置, 使用作用域插槽已经把整个obj对象(包含id)带出来了
MyTable.vue
- MyGoodsList.vue - 注册点击事件
<button class=“btn btn-danger btn-sm”
@click=“removeBtn(scope.row.id)”
删除
2. my-goods-list.vue
根据 id 删除
removeBtn(id){
let index = this.list.findIndex(obj => obj.id === id)
this.list.splice(index, 1)
},
3.8 案例-tabbar-添加tab
目标: 实现点击tab按钮, 出现输入框自动获取焦点, 失去焦点关闭input, 回车新增tag, esc清空内容
Vue 编码基础
2.1.1. 组件规范
2.1.2. 模板中使用简单的表达式
2.1.3 指令都使用缩写形式
2.1.4 标签顺序保持一致
2.1.5 必须为 v-for 设置键值 key
2.1.6 v-show 与 v-if 选择
2.1.7 script 标签内部结构顺序
2.1.8 Vue Router 规范
Vue 项目目录规范
2.2.1 基础
2.2.2 使用 Vue-cli 脚手架
2.2.3 目录说明
2.2.4注释说明
2.2.5 其他