Vue自定义指令原来这么简单,web前端开发怎样自学

89 阅读9分钟

views/04_UseSlot.vue使用

<template #content>

寒雨连江夜入吴,

平明送客楚山孤。

洛阳亲友如相问,

一片冰心在玉壶。

v-slot可以简化成#使用

v-bind可以省略成: v-on: 可以省略成@ 那么v-slot: 可以简化成#

总结: slot的name属性起插槽名, 使用组件时, template配合#插槽名传入具体标签

1.6 组件进阶 - 作用域插槽

目标: 子组件里值, 在给插槽赋值时在父组件环境下使用

复习: 插槽内slot中显示默认内容

例子: 默认内容在子组件中, 但是父亲在给插槽传值, 想要改变插槽显示的默认内容

口诀:

  1. 子组件, 在slot上绑定属性和子组件内的值

  2. 使用组件, 传入自定义标签, 用template和v-slot=“自定义变量名”

  3. scope变量名自动绑定slot上所有属性和值

components/05/Pannel.vue - 定义组件, 和具名插槽, 给slot绑定属性和值

views/05_UseSlot.vue

总结: 组件内变量绑定在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:

"yun.itheima.com/Upload/./Im…",

},

{

name: "小黑同学",

age: 25,

headImgUrl:

"yun.itheima.com/Upload/./Im…",

},

{

name: "智慧同学",

age: 21,

headImgUrl:

"yun.itheima.com/Upload/./Im…",

},

],

例子: 我想要给td内显示图片, 需要传入自定义的img标签

在这里插入图片描述

正确做法:

​ 在MyTable.vue的td中准备占位, 但是外面需要把图片地址赋予给src属性,所以在slot上把obj数据绑定

components/06/MyTable.vue - 正确代码

​ 在UseTable使用MyTable的时候, template上v-slot绑定变量, 传入img组件设置图片地址

总结: 插槽可以自定义标签, 作用域插槽可以把组件内的值取出来自定义内容

2. 自定义指令


自定义指令文档

除了核心功能默认内置的指令 (v-modelv-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, 自定义操作

3. 案例-tabbar


完成如下案例和各步功能

在这里插入图片描述

知识点:

  • 组件封装

  • 动态组件

  • 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 - 标签模板

.my-tab-bar { position: fixed; left: 0; bottom: 0; width: 100%; height: 50px; border-top: 1px solid #ccc; display: flex; justify-content: space-around; align-items: center; background-color: white; .tab-item { display: flex; flex-direction: column; align-items: center; } } .current { color: #1d7bff; }

MyTabBar.vue正确代码(不可复制)

不要忘了把tabList数组从App.vue -> MyTabBar.vue

3.2 案例-tabbar-底部高亮

目标: 点击底部导航实现高亮效果

  • 需求: 点击底部实现高亮效果

分析:

​ ①: 绑定点击事件, 获取点击的索引

​ ②: 循环的标签设置动态class, 遍历的索引, 和点击保存的索引比较, 相同则高亮

效果演示:

在这里插入图片描述

MyTabBar.vue(正确代码)

3.3 案例-tabbar-组件切换

目的: 点击底部导航, 切换页面组件显示

需求: 点击底部切换组件

分析:

​ ①: 底部导航传出动态组件名字符串到App.vue

​ ②: 切换动态组件is属性的值为要显示的组件名

效果演示:

在这里插入图片描述

补充: 给内容div.app- 设置上下内边距

App.vue - 引入并注册

.main{ padding-top: 45px; padding-bottom: 51px; }

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请求数据回来

​ ③: 请求地址: www.escook.cn/api/goods

​ ④: 传入MyTable.vue中循环数据显示

​ ⑤: 给删除按钮添加bootstrap的样式: btn btn-danger btn-sm

效果演示:

在这里插入图片描述

MyTable.vue - 准备table整个表格标签和样式(可复制)

.my-goods-list { .badge { margin-right: 5px; } }

使用axios请求数据, 把表格页面铺设出来

main.js - 注册axios配置默认地址

import axios from "axios";

axios.defaults.baseURL = "www.escook.cn";

MyGoodsList.vue - 使用axios请求数据, 把数据传入给MyTable.vue里循环铺设

MyTable.vue里正确代码(不可复制)

.my-goods-list { .badge { margin-right: 5px; } }

3.5_案例-tabbar-商品表格-插槽

目标: 使用插槽技术, 和作用域插槽技术, 给MyTable.vue组件, 自定义列标题, 自定义表格内容

  • 需求: 允许用户自定义表格头和表格单元格内容

分析:

​ ①: 把MyTable.vue里准备slot

​ ②: 使用MyTable组件时传入具体标签

步骤:

  1. 提高组件复用性和灵活性, 把表格列标题thead部分预留标签, 设置name属性

  2. 使用MyTable.vue时, 传入列标题标签

  3. 表格内容td部分也可以让组件使用者自定义, 也给tbody下tr内留好标签和name属性名

  4. 使用插槽需要用到插槽内的obj对象上的数据, 使用作用域插槽技术

在这里插入图片描述

MyTable.vue - 留好具名插槽

MyGoodsList.vue 使用

<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徽章: v4.bootcss.com/docs/compon…

MyGoodsList.vue - 插槽

<span v-for="(str, ind) in scope.row.tags" :key="ind"

class="badge badge-warning"

{{ str }}

下面额外添加样式

.my-goods-list { .badge { margin-right: 5px; } }

3.7 案例-tabbar-商品表格-删除功能

目标: 点击删除对应这条数据

  • 需求: 点击删除按钮删除数据

分析:

​ ①: 删除按钮绑定点击事件

​ ②: 作用域插槽绑定id值出来

​ ③: 传给删除方法, 删除MyGoodsList.vue里数组里数据

效果演示

在这里插入图片描述

提示: id在MyTable.vue里, 但是MyGoodsList.vue里要使用, 而且在插槽位置, 使用作用域插槽已经把整个obj对象(包含id)带出来了

MyTable.vue

react和vue的比较

相同 1)vitual dom 2)组件化 3)props,单一数据流

不同点 1)react是jsx和模板;(jsx可以进行更多的js逻辑和操作) 2)状态管理(react) 3)对象属性(vue) 4)vue:view——medol之间双向绑定 5)vue:组件之间的通信(props,callback,emit)

开源分享:docs.qq.com/doc/DSmRnRG…