学习笔记--Vue

01-Vue基本概念

一、为何学Vue

目标

更少的时间,更多的活。开发网站速度快。

例子

把数组数据-循环铺设到li中, 看看分别如何做的?

1、原生js做法

    2、Vue.js做法

  • {{item}}
  • (vue的底层还是原生js)

    开发更加的效率和简洁, 易于维护, 快!快!快!就是块 (甚至测试, Java, Python工程师都要学点vue, 方便与前端沟通)

    现在很多项目都是用vue开发的

    市场上90%工作都要求会vue, 会vue拿高薪, 甚至java或测试都要学点vue

    小结

    为什么学 Vue
    1、开发更快,更高效
    2、企业开发都在使用
    3、前端工程师必备技能,高薪

    二、Vue是什么

    logo镇楼

    学习笔记--Vue_第1张图片

    渐进式javacript框架, 一套拥有自己规则的语法

    官网地址: Vue.js - 渐进式 JavaScript 框架 | Vue.js (作者: 尤雨溪)

    尤雨溪:大学专业并非是计算机专业,在大学期间他学习专业是室内艺术和艺术史,后来读了美术设计和技术的硕士,正是在读硕士期间,他偶然接触到了JavaScript ,从此被这门编程语言深深吸引,开启了自己的前端生涯。

    2014 年 2 月,Vue.js 正式发布

    2015 年 10 月 27 日,正式版发布 1.0.0

    2016 年 4 月 27 日,发布 2.0 的预览版本

    1、什么是渐进式

    渐进式: 逐渐进步, 想用什么就用什么, 不必全都使用

    学习笔记--Vue_第2张图片

    逐渐使用,逐渐进步

    简单来说:一辆车(轮子+发动机)-> 方向盘 -> 车灯 -> 翅膀 = 能飞的汽车

    Vue渐进式: Vue从基础开始, 会循序渐进向前学习, 如下知识点可能你现在不明白, 但是学完整个vue回过头来看, 会很有帮助

    声明式渲染 -> 组件系统 -> 客户端路由 -> 大规模状态管理 -> 构建工具

    学习笔记--Vue_第3张图片

    2、什么是库和框架

    补充概念:

    库:  封装的属性或方法 (例jquery.js)

    框架: 拥有自己的规则和元素, 比库强大的多 (例vue.js)

    学习笔记--Vue_第4张图片

    学习笔记--Vue_第5张图片

    • 茅草屋 -> 随意加盖
    • 大厦的脚手架 -> 遵守规则

    三、Vue学习的方式

    • 传统开发模式:基于html/css/js文件开发vue

      学习笔记--Vue_第6张图片

    • 工程化开发方式:在webpack环境中开发vue,这是最推荐, 企业常用的方式

      学习笔记--Vue_第7张图片

    1、Vue如何学

    1. 每天的知识点自测最好做到了如指掌 - 做不到只能花30分钟去记住结论和公式
    2. 记住vue指令作用, 基础语法 - 弄一个字典(一一映射关系)

    第一列:某个知识点

    第二列:语法示列

    第三列:当前知识点的详细介绍

    第四列:当前知识点的应用场景

    1. 在课上例子, 练习, 案例, 作业, 项目中, 反复磨炼使用

    例子、项目,没有标准答案,以完成功能为导向。

    实现功能,不是最终目的。同样一个功能,自己思考,还有没有其他的写法,其他的实现思路。

    1. 学会查找问题的方式和解决方式(弄个报错总结.md, 避免反复进坑)

    遇到报错,先翻译。翻译完了再根据报错内容,查找bug

    2、总结

    vue是渐进式框架, 有自己的规则, 我们要记住语法, 特点和作用, 反复磨炼使用, 多总结

    在哪里书写 Vue 代码呢?

    在工程化环境下用 Vue 开发项目。

    02-Vue基础-@vue/cli脚手架

    一、@vue/cli 脚手架介绍

    1、思考

    1、新的开发模式是不是离不开 webpack?

    2、自己配置 webpack 是不是非常痛苦?

    3、有没有一套搭建好的,拿来即用的环境呢?

    2、目标

    webpack自己配置环境很麻烦, 下载@vue/cli包,用vue命令创建脚手架项目

    3、介绍

    • @vue/cli是Vue官方提供的一个全局模块包(得到vue命令), 此包用于创建脚手架项目
      脚手架是为了保证各施工过程顺利进行而搭设的工作平台

    学习笔记--Vue_第8张图片

    4、@vue/cli的好处

    开箱即用
    0配置webpack
    babel支持
    css, less支持
    开发服务器支持

    5、小结

    需要自己配置 webpack 吗?

    Vue 官方提供了@vue/cli 包 - 可以创建脚手架项目

    脚手架的好处

    0 配置开箱即用,基于它开发我们的项目

    二、@vue/cli安装

    1、思考

    有了 vue 命令,如何创建一套脚手架项目?

    2、目标

    把@vue/cli模块包按到全局, 电脑拥有vue命令, 才能创建脚手架工程

    3、步骤

    1、全局安装命令

    yarn global add @vue/cli
    # OR
    npm install -g @vue/cli

    注意: 如果半天没动静(95%都是网速问题), 可以ctrl+c:停止重新来、换一个网继续重来

    2、查看vue脚手架版本

    vue -V

    4、总结

    1、如何安装全局包?

    yarn global add 包名 / npm install 包名 -g

    2、我们得到什么?

    全局包会在计算机中配置全局命令(例:vue 命令)

    三、@vue/cli 创建项目启动服务

    1、思考

    有了 vue 命令,如何创建一套脚手架项目?

    2、目标

    使用vue命令, 创建脚手架项目

    注意: 项目名不能带大写字母, 中文和特殊符号

    3、步骤

    1. 创建项目
    # vue和create是命令, vuecli-demo是文件夹名
    vue create vuecli-demo
    1. 选择模板
      可以上下箭头选择, 弄错了ctrl+c重来

    学习笔记--Vue_第9张图片

    选择用什么方式下载脚手架项目需要的依赖包

    学习笔记--Vue_第10张图片

    1. 回车等待生成项目文件夹+文件+下载必须的第三方包们

    学习笔记--Vue_第11张图片

    1. 进入脚手架项目下, 启动内置的热更新本地服务器
    cd vuecil-demo
    
    npm run serve
    # 或
    yarn serve

    只要看到绿色的 - 啊. 你成功了(底层node+webpack热更新服务)

    打开浏览器输入上述地址

    学习笔记--Vue_第12张图片

    3、总结

    vue命令创建工程目录, 项目内置webpack本地热更新服务器, 帮我们打包项目预览项目

    1、如何创建一个开箱即用的脚手架项目

    vue create 项目名

    2、如何在网页浏览这个项目

    yarn serve 启动本地热更新开发服务器

    四、@vue/cli 目录和代码分析

    1、目标

    讲解重点文件夹, 文件的作用, 以及文件里代码的意思

     vuecil-demo        # 项目目录
        ├── node_modules # 项目依赖的第三方包
        ├── public       # 静态文件目录
          ├── favicon.ico# 浏览器小图标
          └── index.html # 单页面的html文件(网页浏览的是它)
        ├── src          # 业务文件夹
          ├── assets     # 静态资源
            └── logo.png # vue的logo图片
          ├── components # 组件目录
            └── HelloWorld.vue # 欢迎页面vue代码文件 
          ├── App.vue    # 整个应用的根组件
          └── main.js    # 入口js文件
        ├── .gitignore   # git提交忽略配置
        ├── babel.config.js  # babel配置
        ├── package.json  # 依赖包列表
        ├── README.md    # 项目说明
    	└── yarn.lock    # 项目包版本锁定和缓存地址

    2、小结

    主要文件及含义

    node_modules下都是下载的第三方包
    public/index.html – 浏览器运行的网页
    src/main.js – webpack打包的入口文件
    src/App.vue – vue项目入口页面
    package.json – 依赖包列表文件

    五、@vue/cli 项目架构了解

    1、思考

    项目入口和个文件关系是什么呢?

    2、目标

    知道项目入口, 以及代码执行顺序和引入关系

    学习笔记--Vue_第13张图片

    3、小结

    main.js、App.vue 和 index.html 作用和关系?

    1、main.js - 项目打包入口 - Vue 初始化

    2、App.vue - Vue 页面主入口

    3、index.html - 浏览器运行的文件

    4、App.vue => main.js => index.html

    六、@vue/cli 自定义配置

    1、目标

    项目中没有webpack.config.js文件,因为@vue/cli用的vue.config.js

    src并列处新建vue.config.js

    /* 覆盖webpack的配置 */
    module.exports = {
      devServer: { // 自定义服务配置
        open: true, // 自动打开浏览器
        port: 3000
      }
    }

    2、小结

    脚手架项目配置文件

    src 文件夹并列处准备 vue.config.js 配置文件

    七、eslint了解

    1、目标

    知道eslint的作用, 和如何暂时关闭, 它是一个代码检查工具

    2、例子

    先在main.js 随便声明个变量, 但是不要使用

    学习笔记--Vue_第14张图片

    观察发现, 终端和页面都报错了

    记住以后见到这样子的错误, 证明你的代码不严谨

    学习笔记--Vue_第15张图片

    学习笔记--Vue_第16张图片

    方式1: 手动解决掉错误, 以后项目中会讲如何自动解决

    方式2: 暂时关闭eslint检查(因为现在主要精力在学习Vue语法上), 在vue.config.js中配置后重启服务

    学习笔记--Vue_第17张图片

    3、小结

    1、eslint 是什么?

    eslint 是代码检查工具,违反规定就报错

    2、如何关闭?

    在 vue.config.js 中设置 lintOnSave 为 false 重启服务器即可

    八、@vue/cli 单vue文件讲解

    1、目标

    单vue文件好处, 独立作用域互不影响

    2、文件详解

    Vue推荐采用.vue文件来开发项目

    template里只能有一个根标签

    vue文件-独立模块-作用域互不影响

    style配合scoped属性, 保证样式只针对当前template内标签生效

    vue文件配合webpack, 把他们打包起来插入到index.html

    
    
    
    
    
    
    
    

    最终: Vue文件配合webpack, 把他们打包起来插入到index.html, 然后在浏览器运行

    3、小结

    单 vue 文件好处

    独立作用域,不再担心变量问题。

    单文件使用注意事项

    要注意 template 里只能有一个根标签

    九、@vue/cli 欢迎界面清理

    1、目标

    我们开始写我们自己的代码, 无需欢迎页面

    src/App.vue默认有很多内容, 可以全部删除留下框

    assets 和 components 文件夹下的一切都删除掉 (不要默认的欢迎页面)

     04-Vue基础-vue指令  

    一、vue基础-插值表达式

    1、思考

    1、以前改变标签内容,如何做?
    2、用 Vue 有没有更简单的方式?

    2、目的

    在dom标签中, 直接插入内容

    3、语法

    又叫: 声明式渲染/文本插值

    语法: {{ 表达式 }}

    
    
    
    
    

    4、总结

    什么是插值表达式

    双大括号,可以把 vue 数据变量显示在标签内

    Vue 中变量声明在哪里

    data 函数返回的对象上,用 key 属性声明

    二、vue基础-MVVM设计模式

    1、思考

    在上个代码基础上,在 devtool 工具改变 M 层的变量,观察 V 层(视图的自动同步)

    为什么数据改变页面自动更新了?

    2、目的

    转变思维,用数据驱动视图改变,操作dom的事, vue源码内干了

    3、设计模式

    是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。

    • MVVM,一种软件架构模式,决定了写代码的思想和层次
      • M:   model数据模型          (data里定义)
      • V:    view视图                   (html页面)
      • VM: ViewModel视图模型  (vue.js源码)

    • MVVM通过数据双向绑定让数据自动地双向同步  不再需要操作DOM
      • V(修改视图) -> M(数据自动同步)
      • M(修改数据) -> V(视图自动同步)

    学习笔记--Vue_第18张图片

    1. 在vue中,不推荐直接手动操作DOM!!!

    2. 在vue中,通过数据驱动视图,不要在想着怎么操作DOM,而是想着如何操作数据!!(思想转变)

    学习笔记--Vue_第19张图片

    4、总结

    vue源码内采用MVVM设计模式思想, 大大减少了DOM操作, 挺高开发效率

    1、什么是设计模式

    设计模式适度代码分层,引入一种架构的概念

    2、MVVM 是什么?

    MVVM(模型、视图、视图模型双向关联的一种设计模式)

    3、MVVM 的好处?

    减少 DOM 操作,提高开发效率

    三、vue指令-v-bind

    1、思考

    以前给 a 标签设置 href 如何做呢?

    2、目标

    给标签属性设置vue变量的值

    3、语法

    插值表达式不能用在html的属性上,如果想要动态的设置html元素的属性,需要使用v-bind指令

    vue指令, 实质上就是特殊的 html 标签属性, 特点:  v- 开头

    每个指令, 都有独立的作用

    • 语法:v-bind:属性名="vue变量"
    • 简写::属性名="vue变量"
    
    我是a标签
    

    4、总结

    把vue变量的值, 赋予给dom属性上, 影响标签显示效果

    如何给 dom 标签的属性,设置 Vue 数据变量?

    :属性名="vue 数据变量"

    四、vue指令-v-on

    1、思考

    以前如何给按钮绑定点击事件呢?

    2、目标

    给标签绑定事件

    3、语法

      • v-on:事件名="要执行的少量代码"
      • v-on:事件名="methods中的函数"
      • v-on:事件名="methods中的函数(实参)"
    • 简写: @事件名="methods中的函数"

    
    

    你要买商品的数量: {{count}}

    4、小结

    1、如何给 dom 标签绑定事件?

    @事件名=“methods 里的函数名”

    2、如何给事件传值呢?

    @事件名=“methods 里的函数名(实参)”

    五、vue指令-v-on事件对象

    1、思考

    1、js 原生如何阻止标签的默认行为?
    2、vue 事件处理函数如何获取事件对象呢?

    2、目标

    vue事件处理函数中, 拿到事件对象

    3、语法

    无传参, 通过形参直接接收

    传参, 通过$event指代事件对象传给事件处理函数

    
    
    

    4、小结

    Vue 事件处理函数,如何拿到事件对象呢?

    1、无传参,直接在形参接收
    2、有传参,手动传入$event 对象

    六、vue指令-v-on修饰符

    1、思考

    1、e.preventDefault()单词很长不好写吧?
    2、有没有一种更简单的方式实现呢?

    2、目标

    在事件后面.修饰符名 - 给事件带来更强大的功能

    3、语法

    @事件名.修饰符="methods里函数"

      • .stop - 阻止事件冒泡
      • .prevent - 阻止默认行为
      • .once - 程序运行期间, 只触发一次事件处理函数
    
    
    

    4、总结

    修饰符给事件扩展额外功能

    vue 有哪些主要修饰符,都有什么功能?

    1、.stop - 阻止事件冒泡

    2、.prevent - 阻止默认行为

    3、.once - 只执行一次事件处理函数

    七、vue指令-v-on按键修饰符

    1、思考

    1、以前我想判断用户是否按下回车怎么做?

    2、鼠标事件有修饰符,那按键有修饰符吗?

    2、目标

    给键盘事件, 添加修饰符, 增强能力

    3、语法

      • @keyup.enter  -  监测回车按键
      • @keyup.esc     -   监测返回按键

    更多修饰符

    
    
    

    4、总结

    多使用事件修饰符, 可以提高开发效率, 少去自己判断过程

    1、按键修饰符如何用?

    @键盘事件.按键修饰符=“methods 里函数名”

    2、有哪些主要按键修饰符?

    1、.enter - 只要按下回车才能触发这个键盘事件函数
    2、.esc - 只要按下取消键才能触发这个键盘事件函数

    八、课上练习-翻转世界

    1、目标

    点击按钮 - 把文字取反显示 - 再点击取反显示(回来了)

    提示把字符串取反赋予回去

    效果演示:

    学习笔记--Vue_第20张图片

    2、思考

    1、如何反转字符串?

    2、视图如何实时更新?

    3、分析

    1、定义变量 message:‘HELLO, WORLD’

    2、插值表达式赋予到dom上, 准备按钮和文字

    3、按钮绑定点击事件和函数

    4、对message值用split拆分, 返回数组

    5、数组元素翻转用reverse方法

    6、再把数组用join拼接成字符串赋予给message

    7、因为Vue是MVVM设计模式, 数据驱动视图, 所以视图自动改变

    正确代码:

    
    
    

    4、总结

    记住方法特点, 多做需求, vue是数据变化视图自动更新, 减少操作DOM时间, 提高开发效率

    点击翻转字符串你有什么收获?

    1、写需求要先静态标签, 再考虑动态效果, 找好第一步干什么

    2、记住方法的特点 – 可以自己总结字典和口诀

    3、Vue是靠数据驱动视图, 只需要关心数据变化即可

    九、vue指令 v-model

    1、思考

    1、js中获取表单的值, 赋予给变量?

    2、js变量改变, 同步显示到表单里?

    3、Vue能否把他们互相关联起来呢?

    2、目标

    把value属性和vue数据变量, 双向绑定到一起

    3、语法

    • 语法: v-model="vue数据变量"
    • 双向数据绑定
      • 数据变化 -> 视图自动同步
      • 视图变化 -> 数据自动同步
    • 演示: 用户名绑定 - vue内部是MVVM设计模式
    
    
    

    4、总结

    本阶段v-model只能用在表单元素上, 以后学组件后讲v-model高级用法

    1、v-model用在哪里?

    暂时只能用在表单标签上

    2、v-model有什么作用?

    把vue的数据变量和表单的value属性双向绑定在一起

    5、扩展

    实现原理:

    代码:

    
    
    
    export default {
      data() {
        return {
          msg: '',
        };
      },
    };

    十、vue指令 v-model绑定不同表单

    1、思考

    1、下拉菜单, 复选框, 单选框如何绑定Vue变量呢?

    2、小结

    1、下拉菜单v-model写在哪里?

    在select, value在option上

    2、v-model用在复选框时, 需要注意什么?

    v-model的vue变量是

    非数组 – 关联的是checked属性

    数组 – 关联的是value属性

    3、vue变量初始值会不会影响表单的默认状态?

    会影响, 因为双向数据绑定-互相影响

    十一、vue指令 v-model修饰符

    1、思考

    1、表单同步到变量里的 数 是什么类型的呢?

    2、能否让v-model转成数值再赋予给变量呢?

    2、目标

    让v-model拥有更强大的功能

    3、语法

    v-model.修饰符="vue数据变量"

      • .number   以parseFloat转成数字类型
      • .trim          去除首尾空白字符
      • .lazy           在change时触发而非inupt时

    
    
    

    3、总结

    v-model修饰符, 可以对值进行预处理, 非常高效好用

    v-model有哪些修饰符, 提高我们编程效率?

    1、.number – 转成数值类型赋予给Vue数据变量

    2、.trim – 去除左右两边空格后把值赋予给Vue数据变量

    3、.lazy – 等表单失去焦点, 才把值赋予给Vue数据变量

    十二、vue指令 v-text和v-html

    1、目的

    更新DOM对象的innerText/innerHTML

    2、语法

      • v-text="vue数据变量"
      • v-html="vue数据变量"
      • 注意: 会覆盖插值表达式

    
    
    

    3、总结

    v-text把值当成普通字符串显示, v-html把值当做html解析

    1、v-text和v-html有什么作用?

    都可以设置标签显示的内容

    2、区别是什么?

    v-text把值当成普通字符串显示
    v-html把值当成标签进行解析显示

    十三、vue指令 v-show和v-if

    1、目标

    控制标签的隐藏或出现

    2、语法

      • v-show="vue变量"
      • v-if="vue变量"

    3、原理

      • v-show 用的display:none隐藏   (频繁切换使用)
      • v-if  直接从DOM树上移除

    4、高级

      • v-else使用

    
    
    

    5、总结

    使用v-show和v-if以及v-else指令, 方便通过变量控制一套标签出现/隐藏

    案例-折叠面板

    1、目标

    点击展开或收起时,把内容区域显示或者隐藏

    学习笔记--Vue_第21张图片

    此案例使用了less语法, 项目中下载模块

    yarn add [email protected] [email protected] -D

    只有标签和样式

    
    
    
    
    

    正确答案:

    
    
    

    十四、vue指令-v-for

    1、目标

    列表渲染, 所在标签结构, 按照数据数量, 循环生成

    2、语法

      • v-for="(值, 索引) in 目标结构"
      • v-for="值 in 目标结构"

    3、目标结构

      • 可以遍历数组 / 对象 / 数字 / 字符串 (可遍历结构)

    注意
    v-for的临时变量名不能用到v-for范围外

    
    
    

    4、总结

    vue最常用指令, 铺设页面利器, 快速把数据赋予到相同的dom结构上循环生成

    十五、v-for-更新监测

    1、目标

    当v-for遍历的目标结构改变, Vue触发v-for的更新

    情况1: 数组翻转

    情况2: 数组截取

    情况3: 更新值

    2、口诀

    数组变更方法, 就会导致v-for更新, 页面更新

    数组非变更方法, 返回新数组, 就不会导致v-for更新, 可采用覆盖数组或this.$set()

    
    
    
    
    

    这些方法会触发数组改变, v-for会监测到并更新页面

    • push()
    • pop()
    • shift()
    • unshift()
    • splice()
    • sort()
    • reverse()

    这些方法不会触发v-for更新

    • slice()
    • filter()
    • concat()

    注意: vue不能监测到数组里赋值的动作而更新, 如果需要请使用Vue.set() 或者this.$set(), 或者覆盖整个数组

    3、总结

    改变原数组的方法才能让v-for更新

    十六、v-for更新性能为何高

    v-for 的默认行为会尝试原地修改元素而不是移动它们。

    详解v-for就地更新流程(可以看ppt动画)

    学习笔记--Vue_第22张图片

    这种 虚拟DOM对比方式, 可以提高性能 - 但是还不够高

    十七、虚拟dom

    1、目标

    了解虚拟DOM的概念

    .vue文件中的template里写的标签, 都是模板, 都要被vue处理成虚拟DOM对象, 才会渲染显示到真实DOM页面上

    2、介绍

    1. 内存中生成一样的虚拟DOM结构(本质是个JS对象)
      因为真实的DOM属性好几百个, 没办法快速的知道哪个属性改变了
      比如template里标签结构


    对应的虚拟DOM结构

    1. 以后vue数据更新
      • 生成新的虚拟DOM结构
      • 和旧的虚拟DOM结构对比
      • 利用diff算法, 找不不同, 只更新变化的部分(重绘/回流)到页面 - 也叫打补丁

    好处1: 提高了更新DOM的性能(不用把页面全删除重新渲染)

    好处2: 虚拟DOM只包含必要的属性(没有真实DOM上百个属性)

    3、总结

    虚拟DOM保存在内存中, 只记录dom关键信息, 配合diff算法提高DOM更新的性能

    在内存中比较差异, 然后给真实DOM打补丁更新上

    学习笔记--Vue_第23张图片

    十八、diff算法

    vue用diff算法, 新虚拟dom, 和旧的虚拟dom比较

    情况1: 根元素变了, 删除重建

    旧虚拟DOM

    123

    新虚拟DOM

    • 123

    情况2: 根元素没变, 属性改变, 元素复用, 更新属性

    旧虚拟DOM

    123

    新虚拟DOM

    123

    十九、key的作用

    情况3: 根元素没变, 子元素没变, 元素内容改变

    无key - 就地更新

    v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key 来提供一个排序提示

    • {{ str }}
    export default { data(){ return { arr: ["老大", "新来的", "老二", "老三"] } }, methods: { addFn(){ this.arr.splice(1, 0, '新来的') } } };

    学习笔记--Vue_第24张图片

    旧 - 虚拟DOM结构 和 新 - 虚拟DOM结构 对比过程

    学习笔记--Vue_第25张图片

    性能不高, 从第二个li往后都更新了

    有key - 值为索引

    • 还是就地更新

    因为新旧虚拟DOM对比, key存在就复用此标签更新内容, 如果不存在就直接建立一个新的

    • {{ str }}
    export default { data(){ return { arr: ["老大", "新来的", "老二", "老三"] } }, methods: { addFn(){ this.arr.splice(1, 0, '新来的') } } };

    key为索引-图解过程 (又就地往后更新了)

    学习笔记--Vue_第26张图片

    学习笔记--Vue_第27张图片

    1. v-for先循环产生新的DOM结构, key是连续的, 和数据对应
    2. 然后比较新旧DOM结构, 找到区别, 打补丁到页面上
      最后补一个li, 然后从第二个往后, 都要更新内容
    3. 口诀: key的值有id用id, 没id用索引

    有key - 值为id

    key的值只能是唯一不重复的, 字符串或数值

    v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key 来提供一个排序提示

    新DOM里数据的key存在, 去旧的虚拟DOM结构里找到key标记的标签, 复用标签

    新DOM里数据的key存在, 去旧的虚拟DOM结构里没有找到key标签的标签, 创建

    旧DOM结构的key, 在新的DOM结构里没有了, 则移除key所在的标签

    
    
    
    
    

    学习笔记--Vue_第28张图片

    学习笔记--Vue_第29张图片

    总结: 不用key也不影响功能(就地更新), 添加key可以提高更新的性能

    06-Vue基础-动态class

    一、思考

    1、JS 判断标签是否应该使用某个类名?

    2、vue 能不能直接在标签里判断?

    二、目标

    用v-bind给标签class设置动态的值

    三、语法

    :class="{类名: 布尔值}"

    
    
    
    
    
    

    四、小结

    如何给标签 class 属性动态赋值?

    :class=“{类名: 布尔值}”, true 使用, false 不用

    五、扩展

    1、多个动态 class,如何处理?

    class=“{类名 1:布尔值 1,class2:布尔值 2}”

    多个 class,用“,”逗号隔开

    动态class

    2、固定 class 如何书写?

    动态class

    class 与 :class 可以并存

    3、class 的数组语法

    data() { return{ activeClass: 'active', errorClass: 'text-danger' } }

    呈现出来的效果:

    4、三元运算

    好好学习

    data() { return { bool: false, }; }, };

    07-Vue基础-动态style

    一、语法

    :style="{css属性: 值}"

    注意:

    1.如果css样式是需要短横线的,需要将短横线删除使用小驼峰命名法

    好好学习天天向上

    2.css属性值需要加引号可以直接引用数值,可以不用设置变量

    好好学习天天向上

    动态style也有动态style对象语法,动态style数组语法,动态style三元运算语法

    
    
    
    
    
    

    08-案例-品牌管理

    一、品牌管理(铺设)

    目标

    数据铺设

    需求

    • 需求1: 把默认数据显示到表格上
    • 需求2: 注意资产超过100的, 都用红色字体标记出来

    细节

    ① 先铺设静态页面 --- 去.md文档里, 复制数据和标签模板

    ② 此案例使用bootstrap, 需要下载, 并导入到工程main.js中

    ③ 用v-for配合默认数据, 把数据默认铺设到表格上显示

    ④ 直接在标签上, 大于100价格, 动态设置red类名

    图示

    学习笔记--Vue_第30张图片

    步骤

    1. 因为案例使用了bootstrap, 工程化开发, 模块化用npm/yarn下载引入使用
    yarn add bootstrap

    2.在main.js - 引入bootstrap

    import "bootstrap/dist/css/bootstrap.css" // 默认找文件夹下的index文件(但是这个不是所以需要写路径)

    3正确代码

    
    
    
    
    
    

    小结

    1、布局用 bootstrap, yarn 下载引入使用

    2、v-for 把数据渲染到表格里

    3、:class 动态判断价格给红色类名

    二、品牌管理(添加资产)

    目标

    数据新增

    需求

    • 需求1: 实现表单数据新增进表格功能
    • 需求2: 判断用户输入是否为空给提示

    分析

    ① 添加资产按钮 – 绑定点击事件
    ② 给表单v-model绑定vue变量收集用户输入内容
    ③ 添加数据到数组中
    ④ 判断用户内容是否符合规定

    图示

    学习笔记--Vue_第31张图片

    在上个案例代码基础上接着写

    
    
    
    
    
    

    小结

    1、@绑定事件

    2、v-model 收集表单数据

    3、.prevent 阻止按钮提交表单刷新页面

    4、v-model 修饰符

    5、数组取最后一个元素

    三、品牌管理(删除)

    目标

    数据删除

    需求

    • 需求1: 点击删除的a标签, 删除数据
    • 需求2: 删除没数据了要提示暂无数据的tfoot

    分析

    ① a标签绑定点击事件
    ② 给事件方法传id
    ③ 通过id, 找到对应数据删除
    ④ 删除光了要让tfoot显示
    ⑤ 删除光了再新增, 有bug(id值问题)需要修复

    图示

    学习笔记--Vue_第32张图片

    在上个案例代码基础上接着写

    
    删除
              
    

    小结

    涉及到了哪些技术点?

    1、事件传 id

    2、删除数组元素方法

    3、id 值判断问题

    四、品牌管理(时间格式化)

    目标

    复制上个案例, 在此基础上, 把表格里的时间用过滤器+moment模块, 格式化成YYYY-MM-DD 格式

    图示

    学习笔记--Vue_第33张图片

    步骤

    1. 下载moment处理日期的第三方工具模块



    1. moment官网文档: 文档 | Moment.js 中文网
    yarn add moment

    1. 定义过滤器, 把时间用moment模块格式化, 返回我们想要的格式

    // 目标: 处理时间
    // 1. 下载moment模块
    import moment from 'moment'
    
    
    // 2. 定义过滤器, 编写内部代码
    filters: { 
        formatDate (val){
            return moment(val).format('YYYY-MM-DD')
        }
    }
    
    
    {{ obj.time | formatDate }}

    五、品牌管理(总价和均价)

    目标

    基于之前的案例, 完成总价和均价的计算效果学习笔记--Vue_第34张图片

    
    
    
    
    
    

    小结

    总价来源于所有数据计算而来的结果, 故采用计算属性

    涉及到的知识点

    1、computed 定义和使用计算属性
    2、数组 reduce 方法累积运算

    09-Vue基础-过滤器

    一、vue过滤器定义使用

    思考

    1、JS 原生如何封装一个字母翻转的函数?

    2、生活当中的过滤器是什么? Vue 中如何实现过滤器?

    目的

    转换格式, 过滤器就是一个函数, 传入值返回处理后的值

    重点

    1、过滤器只能用在, 插值表达式和v-bind表达式

    2、Vue中的过滤器场景

    • 字母转大写, 输入"hello", 输出"HELLO"
    • 字符串翻转, "输入hello, world", 输出"dlrow ,olleh"

    语法

    • Vue.filter("过滤器名", (值) => {return "返回处理后的值"})
    Vue.filter('reverse', (val, s) => {
      return val.split('').reverse().join(s);
    });
    filters: {过滤器名字: (值) => {return "返回处理后的值"}
    filters: {
      reverse(val) {
        return val.split('').reverse().join(s);
      },
    },

    例子

    • 全局定义“字母都大写”的过滤器
    • 局部定义“字符串翻转”的过滤器
    
    
    
    

    总结

    把值转成另一种形式, 使用过滤器, Vue3用函数替代了过滤器.

    全局注册最好在main.js中注册, 一处注册到处使用

    二、传参和多过滤器

    目标

    可同时使用多个过滤器, 或者给过滤器传参

    语法

      • 过滤器传参:   vue变量 | 过滤器(实参)
      • 多个过滤器:   vue变量 | 过滤器1 | 过滤器2

    
    
    
    

    总结

    过滤器可以传参, 还可以对某个过滤器结果, 后面在使用一个过滤器

    1、多个过滤器使用?

    vue 变量 | 过滤器 1 | 过滤器 2

    2、如何给过滤器传额外值

    vue 变量 | 过滤器(值)

    10-Vue基础-计算属性-computed

    一、vue计算属性-computed

    一个数据, 依赖另外一些数据计算而来的结果

    语法

    {{ '计算属性名' }}

    computed: {
        "计算属性名" () {
            return "值"
        }
    }

    需求

    
    
    
    

    注意

    计算属性也是vue数据变量, 所以不要和data里重名, 用法和data相同

    总结

    一个数据, 依赖另外一些数据计算而来的结果

    1、计算属性使用场景?

    当变量的值, 需要通过别人计算而得来

    2、计算属性特点?

    函数内使用的变量改变, 重新计算结果返回

    3、计算属性注意事项?

    计算属性名和 data 里名字不能重复

    二、vue计算属性-缓存特性

    目标

    计算属性是基于它们的依赖项的值结果进行缓存的,只要依赖的变量不变, 都直接从缓存取结果学习笔记--Vue_第35张图片

    代码

    
    
    
    

    总结

    计算属性根据依赖变量结果缓存, 依赖变化重新计算结果存入缓存, 比普通方法性能更高

    1、计算属性好处是?

    带缓存
    依赖项不变, 直接从缓存取
    依赖项改变, 函数自动执行并重新缓存

    2、计算属性使用场景?

    当变量值, 依赖其他变量计算而得来才用

    三、vue计算属性-完整写法

    目标:计算属性也是变量

    语法:

    computed: {
        "属性名": {
            set(值){
                
            },
            get() {
                return "值"
            }
        }
    }

    给关联v-model需要给计算属性变量赋值的时候需要用到计算属性完整写法

    
    
    
    
    
    

    set 接收要赋予的值
    get 里要返回给这个计算属性具体值

    11-案例-全选和反选

    一、小选影响全选

    一、小选影响全选

    需求

    小选框都选中(手选), 全选自动选中

    分析

    ① 先静态后动态, 从.md拿到静态标签和数据

    ② 循环生成复选框和文字, 对象的c属性和小选框的选中状态, 用v-model双向绑定

    ③ 定义isAll计算属性, 值通过小选框们统计c属性状态得来

    图示

    学习笔记--Vue_第36张图片

    代码

    
    
    

    正确代码,不可复制

    
    
    

    小结

    小选框如何影响全选框选中状态的?

    v-model 给全选框绑定 isAll 计算属性

    isAll 计算属性里返回统计小选框选中状态结果

    二、全选影响小选

    需求

    • 需求1: 获取到全选状态 – 改装isAll计算属性
    • 需求2: 全选状态同步给所有小选框

    分析

    ①: isAll改成完整写法, set里获取到全选框, 勾选的状态值

    ②: 遍历数据数组, 赋给所有小选框v-model关联的属性

    图示

    学习笔记--Vue_第37张图片

    代码

    小结

    全选如何影响小选框选中状态的?

    1、小选框 v-model, 关联数组里对象的 c 属性

    2、isAll 计算属性的 set 方法, 拿到全选框状态

    3、状态值赋给, 数组里每个对象的 c 属性

    三、反选

    需求

    点击反选, 让所有小选框, 各自取相反勾选状态

    分析

    1、小选框的勾选状态, 在对象的 c 属性

    2、遍历所有对象, 把对象的 c 属性取相反值赋予回去即可

    图示

    学习笔记--Vue_第38张图片

    代码

    
    
    

    小结

    反选如何实现的?

    遍历每个对象, 把 c 属性的值取反再赋予回去

    12-Vue基础-侦听器

    目标

    侦听到name值得改变

    语法

    watch:{
    变量名(newVal,oldVal){
    
    }
    }

    代码

    
    
    
    
    

    小结

    如何侦听到某个变量值改变呢?

    使用 watch 配置项, key 是要侦听的 data/计算属性名

    二、深度侦听和立即执行

    可以执行深度侦听

    语法

    watch: {
      user: {
        handler(newVal, oldVal) {
          // user里的对象
          console.log(newVal, oldVal);
        },
        deep: true,
        immediate: true,
      },
    },

    代码

    
    
    
    

    小结

    1、如何侦听一个对象/数组呢?

    把侦听器写成对象形式, 给 handler 方法和 deep:true

    2.一打开网页立马执行

    immediate: true

    13-计算属性和侦听器的区别

    计算属性(computed)

    属性检测(watch)

    首次运行

    首次不运行

    调用时需要在模板中渲染,修改计算所依赖元数据

    调用时只需修改元数据

    默认深度依赖

    默认浅度观测

    1、功能:computed是计算属性;watch是监听一个值的变化执行对应的回调。
    2、是否调用缓存:computed函数所依赖的属性不变的时候会调用缓存;watch每次监听的值发生变化时候都会触发。
    3、是否调用return:computed必须有;watch可以没有。
    4、使用场景:computed的值受多个属性影响的时候;例如购物车商品结算;watch当一条数据影响多条数据的时候,例如搜索框。

    14-Vue组件

    一、为什么用组件

    思考

    1、以前遇到重复的标签, 如何做的?

    2、效率或独立性高吗, 担心变量重名?

    思考

    1、以前遇到重复的标签, 如何做的?

    2、效率或独立性高吗, 担心变量重名?

    3、代码实现

    import Pannel from './components/Pannel';
    export default {
      components: {
        //注册组件
        //'标签名': '组件名',
       // Pannel: Pannel,
    //当标签名和组件名一致的时候可以缩写
            Pannel
      },
    };

    引入后可以直接引用

    小结

    1、遇到重复标签想复用?

    封装成组件

    2、组件好处?

    各自独立, 便于复用

    二、vue组件的概念

    思考

    组件的概念,什么是组件?

    重点

    1、组件是可复用的 Vue 实例, 封装标签, 样式和 JS 代码。

    2、组件化 :封装的思想,把页面上 可重用的部分 封装为 组件,从而方便项目的开发和维护。

    3、一个页面, 可以拆分成一个个组件, 一个组件就是一个整体, 每个组件可以有自己独立的结构样式和行为(html, css 和 js)。

    学习笔记--Vue_第39张图片

    小结

    1、组件是什么?

    可复用的 vue 实例, 封装标签, 样式, JS

    2、什么时候封装组件?

    遇到重复标签, 可复用的时候

    3、组件好处?

    各自独立, 互不影响

    三、vue组件的基本使用

    思考

    如何创建和使用组件?

    重点

    每个组件都是一个独立的个体, 代码里体现为一个独立的.vue 文件

    口诀: 哪部分标签复用, 就把哪部分封装到组件内

    (重要): 组件内template只能有一个根标签

    (重要): 组件内data必须是一个函数, 独立作用域

    1、创建组件, 封装要复用的标签, 样式, JS 代码

    2、注册组件

    全局注册 – main.js 中

    import Vue from 'vue';
    import App from './App.vue';
    import 组件对象 from 'vue文件路径';
    Vue.component('组件名', 组件对象);

    局部注册 – 某.vue 文件内 – 语法如图

    import 组件对象 from 'vue文件路径';
    export default {
      components: {
        PannelL: Pannel,
      },
    };

    3、使用组件

    小结

    1、创建和使用组件步骤?

    创建.vue 文件,封装标签 – 样式 – JS 进去

    注册组件 (全局 / 局部)

    使用组件 (组件名用作标签)

    2、组件运行结果?

    把组件标签最终替换成, 封装的组件内标签

    四、vue组件scoped的作用

    思考

    组件内的 scoped 是如何工作的?

    目的

    解决多个组件样式名相同, 冲突问题

    需求: div标签名选择器, 设置背景色

    问题: 发现组件里的div和外面的div都生效了

    解决: 给Pannel.vue组件里style标签上加scoped属性即可

    语法

    在style上加入scoped属性, 就会在此组件的标签上加上一个随机生成的data-v开头的属性

    而且必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到

    
    

    App.vue

    
    
    
    
    
    

    子组件内, 定义变量, 准备接收, 然后使用变量

    
    
    
    
    

    2、父组件

    父组件(App.vue)内, 要展示封装的子组件(MyProduct.vue)

    步骤:引入组件, 注册组件, 使用组件, 传值进去

    
    
    
    
    
    

    小结

    组件封装复用的标签和样式, 而具体数据要靠外面传入

    1、什么时候需要父传子技术?

    从一个 vue 组件里把值传给另一个 vue 组件(父- >子)

    2、父传子口诀(步骤)是什么?

    子组件内, props 定义变量, 在子组件使用变量

    父组件内, 使用子组件, 属性方式给 props 变量传值

    二、组件通信父向子-配合循环

    思考

    1、能循环使用组件吗?

    2、每次循环使用组件, 独立向组件内传值?

    目的

    把数据循环分别传入给组件内显示

    目标

    父组件 - > 子组件 循环使用-传值

    数据

    list: [
            {
              id: 1,
              proname: "超级好吃的棒棒糖",
              proprice: 18.8,
              info: "开业大酬宾, 全场8折",
            },
            {
              id: 2,
              proname: "超级好吃的大鸡腿",
              proprice: 34.2,
              info: "好吃不腻, 快来买啊",
            },
            {
              id: 3,
              proname: "超级无敌的冰激凌",
              proprice: 14.2,
              info: "炎热的夏天, 来个冰激凌了",
            },
          ],

    代码

    
    
    
    
    
    

    重点

    1、key 属性绑定 id

    2、组件属性加冒号,因为传的是变量

    小结

    循环使用组件注意事项?

    每次循环, 变量和组件, 都是独立的

    三、组件通信-单项数据流

    思考

    1、子组件内想实现砍价功能, 点一次按钮砍掉价格?

    2、子组件内能改变, 父传入的数据吗?

    重点

    1、子组件修改, 不通知父级, 会造成数据不一致性,子数据来源于数据

    2、Vue 规定 props 里的变量, 本身是只读的,不能用来赋值

    原则

    1、父组件的数据发生了改变,子组件会自动跟着变
    2、子组件不能直接修改父组件传递过来的props  props是只读的

    小结

    1、为何不建议, 子组件修改父组件传过来的值?

    父子数据不一致, 而且子组件是依赖父传入的值

    2、什么是单向数据流?

    从父到子的数据流向, 叫单向数据流

    3、props 里定义的变量能修改吗?

    不能, props 里的变量本身是只读的

    四、组件通信-子向父

    思考

    那子组件如何才能修改父组件里的数据呢?

    需求

    课上例子, 砍价功能, 子组件点击实现随机砍价功能

    
    
    
    
    
    

    学习笔记--Vue_第41张图片

     因为单向数据流问题,会导致报错

    重点

    子组件触发父自定义事件方法

    语法

    父: @自定义事件名="父methods函数"

    子: this.$emit("自定义事件名", 传值) - 执行父methods里函数代码

    1、父组件

    绑定自定义事件和事件处理函数

    export default {
      methods: {
        fn('参数'){
          // 逻辑代码
        }
      }
    };

    2、子组件

    恰当的时机, 触发父组件自定义事件, 导致父 methods 里事件处理函数执行

    export default {
      methods: {
        subFn() {
          //this.$emit('自定义事件名', 值);
          this.$emit('subprice', '值'); // 子向父
        },
      },
    };

    小结

    1、什么时候使用子传父技术?

    当子想要去改变父里的数据

    2、子传父如何实现?

    父组件内, 给组件@自定义事件="父 methods 函数" 子组件内, 恰当时机

    this.$emit('自定义事件名', 值);

    学习笔记--Vue_第42张图片

     传值后可以相互影响相互改变

    五、跨组件通信

    思考

    两个没有任何引入关系的组件, 要如何互相通信呢?

    重点

    EventBus

    常用于跨组件通信时使用

    两个组件的关系非常的复杂,通过父子组件通讯是非常麻烦的。这时候可以使用通用的组件通讯方案:事件总线(event-bus)

    学习笔记--Vue_第43张图片

    步骤

    1、src/EventBus/index.js – 创建空白 Vue 对象并导出

    2、在要接收值的组件(List.vue) eventBus.$on('事件名', 函数体)

    3、在要传递值的组件(MyProduct.vue) eventBus.$emit('事件名', 值)

    语法

    EventBus/index.js- 定义事件总线bus对象

    import Vue from 'vue'
    // 导出空白vue对象
    export default new Vue()

    List.vue注册事件 - 等待接收要砍价的值 (直接复制) - 准备兄弟页面

    
    
    
    
    

    List.vue正确代码(EventBus接收方)

    
    
    
    
    

    小结

    1、什么时候使用 eventBus 技术?

    当 2 个没有引用关系的组件之间要通信传值

    2、eventBus 技术本质是什么?

    空白 Vue 对象, 只负责emit

    六、拓展(组件通信的方式)

    1、子父组件通信

    2、事件总线(EventBus)(适合小型项目:页面少、功能少)

    3、依赖注入(不推荐使用)(数据流向不好追溯)

    4、vuex(企业级项目常用)

    5、浏览器缓存

    6、etc。。。。

    Vue生命周期

    一、人的生命周期

    思考

    1、什么是生命周期?

    2、Vue所谓的生命周期又是什么?

    重点

    一组件从 创建销毁 的整个过程就是生命周期

    学习笔记--Vue_第44张图片

    Vue_生命周期

    学习笔记--Vue_第45张图片

    二、钩子函数

    目标

    Vue 框架内置函数,随着组件的生命周期阶段,自动执行

    作用

    特定的时间点,执行特定的操作

    场景

    组件创建完毕后,可以在created 生命周期函数中发起Ajax 请求,从而初始化 data 数据

    分类

    4大阶段8个方法

    • 初始化
    • 挂载
    • 更新
    • 销毁

    阶段

    方法名

    方法名

    初始化

    beforeCreate

    created

    挂载

    beforeMount

    mounted

    更新

    beforeUpdate

    updated

    销毁

    beforeDestroy

    destroyed

    官网文档

    下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。

    学习笔记--Vue_第46张图片

    小结

    1、如何知道Vue生命周期到达了什么阶段?

    使用钩子函数

    2、钩子函数有哪些?

    初始化 / 挂载 / 更新 / 销毁

    三、初始化阶段

    目标

    掌握初始化阶段2个钩子函数作用和执行时机

    重点

    1.new Vue() – Vue实例化(组件也是一个小的Vue实例)

    2.Init Events & Lifecycle – 初始化事件和生命周期函数

    3.beforeCreate – 生命周期钩子函数被执行

    4.Init injections&reactivity – Vue内部添加data和methods等

    5.created – 生命周期钩子函数被执行, 实例创建

    6.接下来是编译模板阶段 –开始分析

    7.Has el option? – 是否有el选项 – 检查要挂到哪里

    没有. 调用$mount()方法

    有, 继续检查template选项

    学习笔记--Vue_第47张图片

    components/Life.vue - 创建一个文件

    App.vue - 引入使用

    
    
    

    小结

    1、Vue实例从创建到编译模板执行了哪些钩子函数?

    beforeCreate / created

    2、created函数触发能获取data?

    能获取data, 不能获取真实DOM

    四、挂载阶段

    思考

    1、我们在template里写的是真实的DOM吗?

    2、哪个钩子函数里能获取真实DOM呢?

    目标

    掌握挂载阶段2个钩子函数作用和执行时机

    重点

    1.template选项检查

    有 - 编译template返回render渲染函数

    无 – 编译el选项对应标签作为template(要渲染的模板)

    2.虚拟DOM挂载成真实DOM之前

    3.beforeMount – 生命周期钩子函数被执行

    4.Create … – 把虚拟DOM和渲染的数据一并挂到真实DOM上

    5.真实DOM挂载完毕

    6.mounted – 生命周期钩子函数被执行

    学习笔记--Vue_第48张图片

    components/Life.vue - 创建一个文件

    
    
    

    小结

    1、Vue实例从创建到显示都经历了哪些钩子函数?

    beforeCreate / created / beforeMount / mounted

    2、created函数里, 能获取真实DOM吗?

    不能获取真实DOM

    3、在什么钩子函数里可以获取真实DOM?

    mounted

    五、更新阶段

    思考

    data数据改变会触发哪些钩子函数呢?

    目标

    掌握更新阶段2个钩子函数作用和执行时机

    重点

    1.当data里数据改变, 更新DOM之前

    2.beforeUpdate – 生命周期钩子函数被执行

    3.Virtual DOM…… – 虚拟DOM重新渲染, 打补丁到真实DOM

    4.updated – 生命周期钩子函数被执行

    5.当有data数据改变 – 重复这个循环

    学习笔记--Vue_第49张图片

    components/Life.vue - 创建一个文件

    准备ul+li循环, 按钮添加元素, 触发data改变->导致更新周期开始

     
      

    小结

    1、什么时候执行updated钩子函数

    当数据发生变化并更新页面后

    2、在哪可以获取更新后的DOM

    在updated钩子函数里

    六、销毁阶段

    目标

    掌握销毁阶段2个钩子函数作用和执行时机

    重点

    1.当$destroy()被调用 – 比如组件DOM被移除(例v-if)

    2.beforeDestroy – 生命周期钩子函数被执行

    3.拆卸数据监视器、子组件和事件侦听器

    4.实例销毁后, 最后触发一个钩子函数

    5.destroyed – 生命周期钩子函数被执行

    学习笔记--Vue_第50张图片

    components/Life.vue - 准备生命周期方法(Life组件即将要被删除)

    主要: App.vue - 点击按钮让Life组件从DOM上移除 -> 导致Life组件进入销毁阶段

    
    
    
    

    小结

    一般在beforeDestroy/destroyed里做什么?

    手动消除计时器/定时器/全局事件

    &ref和&nextTick

    一、ref获取原生dom元素

    思考

    1、Vue中如何获取真实DOM元素?

    2、还有没有更多方式?

    目标

    通过id或ref属性获取原生DOM

    在mounted生命周期 – 2种方式获取原生DOM标签

    1、目标标签 – 添加id / ref

    2、恰当时机, 通过id / 通过ref属性 获取目标标签

    重点

    获取原生dom

    mounted(){ //mounted 生命周期内部 console.log(document.getElementById("h")); // h1 console.log(this.$refs.myH); // h1 },

    小结

    Vue中如何获取原生DOM呢?

    用id属性或者ref属性都可以

    二、ref属性组件对象

    思考

    Vue中能否获取组件对象呢?

    目标

    通过ref属性获取组件对象

    1、创建Demo组件, 写一个方法

    2、App.vue使用Demo组件, 给ref属性-名字随意

    3、恰当时机, 通过ref属性 获取组件对象, 可调用组件对象里方法等

    代码

    components/Child/Demo.vue

    
    

    More.vue - 获取组件对象 - 调用组件方法

    
    

    小结

    1、如何获取组件对象呢?

    目标组件添加ref属性

    this.$refs.名字 获取组件对象

    2、拿到组件对象能做什么?

    调用组件里的属性/方法

    三、nextTick基础使用

    思考

    data数据改变, 马上获取DOM里的内容如何写?

    目标

    目标:点击改data,获取原生DOM内容

    1、创建标签显示数据

    2、点击+1,马上获取原生DOM内容

    原因: Vue更新DOM是异步的

    目标:等DOM更新后, 触发此方法里函数体执行

    1、语法: this.$nextTick(函数体)

    代码

    
    
    

    小结

    1、data改变更新DOM是同步还是异步的?

    异步

    2、我们可以在哪里访问到更新后的DOM呢?

    this.$nextTick里的函数体

    updated生命周期钩子函数

    四、nextTick使用场景

    思考

    $nextTick还有什么使用场景呢?

    目标

    点击按钮自身隐藏, 出现输入框并马上处于激活状态

    效果演示:

    学习笔记--Vue_第51张图片

    代码

    
    
    

    小结

    1、$nextTick函数原地返回什么?

    Promise对象

    2、如何在JS中主动触发标签的事件呢?

    获取到DOM对象, 调用事件方法

    五、组件的name

    name的作用

    1、递归组件的(组件调用自身组件)

    这个时候被递归的组件name必写

    2、组件的缓存keep-alive

    一个组件需不需要被缓存,也是需要通过name属性来控制。

    3、vue调试插件DevTools

    显示组件的name,语义化

    组件进阶

    一、组件进阶 - 动态组件

    思考

    问题1: 如何切换2个组件, 互斥的显示或隐藏呢?

    问题2: 不用v-if可以实现吗?有没有简单的方式?

    目标

    多个组件使用同一个挂载点,并动态切换,这就是动态组件

    需求

    完成一个注册功能页面, 2个按钮切换, 一个填写注册信息, 一个填写用户简介信息

    效果如下:

    学习笔记--Vue_第52张图片

    步骤&代码

    1. 准备被切换的 - UserName.vue / UserInfo.vue 2个组件
    2. 引入到UseDynamic.vue注册
    3. 准备变量来承载要显示的"组件名"
    4. 设置挂载点, 使用is属性来设置要显示哪个组件
    5. 点击按钮 – 修改comName变量里的"组件名"
    
    
    

    在App.vue - 引入01_UseDynamic.vue并使用显示

    小结

    vue内置component组件, 配合is属性, 设置要显示的组件名字

    1. 什么是动态组件?
      在同一个挂载点, 可以切换显示不同组件
    2. 如何使用动态组件?
      vue内置的component组件, 配合is属性
    3. 如何切换?
      改变is属性的值, 为要显示的组件名即可

    二、组件进阶 - 组件缓存

    思考

    问题1: 频繁的切换会不会导致组件频繁创建和销毁呢?

    问题2: 性能高不高呢?

    问题3: 如何避免这个问题?

    目标

    组件切换会导致组件被频繁销毁和重新创建, 性能不高

    使用Vue内置的keep-alive组件, 可以让包裹的组件保存在内存中不被销毁

    演示1: 可以先给UserName.vue和UserInfo.vue 注册created和destroyed生命周期事件, 观察创建和销毁过程

    演示2: 使用keep-alive内置的vue组件, 让动态组件缓存而不是销毁

    语法

    Vue内置的keep-alive组件 包起来要频繁切换的组件

    代码&步骤

    02_UseDynamic.vue

    补充生命周期

    • activated - 激活
    • deactivated - 失去激活状态

    总结

    keep-alive可以提高组件的性能, 内部包裹的标签不会被销毁和重新创建, 触发激活和非激活的生命周期方法。

    1. 如何进行组件缓存?
      vue内置的keep-alive组件把要缓存的组件包起来
    2. 组件缓存好处?
      不会频繁的创建和销毁组件, 页面更快呈现

    三、组件进阶 - 激活和非激活

    思考

    如何知道组件被切走了, 还是切换回来了呢?

    目标

    被缓存的组件不再创建和销毁, 而是激活和非激活

    补充2个钩子方法名:

    activated – 激活时触发

    deactivated – 失去激活状态触发

    小结

    如何知道缓存的组件是出现还是消失了?

    activated – 获得激活状态

    deactivated – 失去激活状态

    拓展

    include="组件Aname"

    组件A会被缓存,其他组件不缓存

    exclude="组件A的name"

    组件A不缓存,其他组件缓存

    四、组件进阶 - 组件插槽

    思考

    问题1: 组件里的数据不确定可以怎么做?

    问题2:组件里的标签不确定怎么办呢?

    目标

    用于实现组件的内容分发, 通过 slot 标签, 可以接收到写在组件标签内的内容

    vue提供组件插槽能力, 允许开发者在封装组件时,把不确定的部分定义为插槽

    插槽例子:

    学习笔记--Vue_第53张图片

    需求

    以前折叠面板案例, 想要实现不同内容显示, 我们把折叠面板里的Pannel组件, 添加组件插槽方式

    学习笔记--Vue_第54张图片

    语法

    1. 组件内用占位
    2. 使用组件时夹着的地方, 传入标签替换slot

    代码&步骤

    03/Pannel.vue - 组件(直接复制)

    
    
    
    
    

    views/03_UserSlot.vue - 使用组件(直接复制)

    框: 在这个基础重复使用组件

    
    
    
    
    

    views/03_UseSlot.vue - 组件插槽使用

    
    
    

    小结

    1. 当组件内某一部分标签不确定怎么办?
      用插槽技术
    2. 插槽具体如何使用?
      先在组件内用slot占位
      使用组件时, 传入具体标签插入
    3. 插槽运行效果?
      传入的标签会替换掉slot显示

    五、组件进阶 - 插槽默认内容

    思考

    问题1: 使用我封装组件的人, 不给slot传标签, 怎么办?

    问题2: 可否设置默认内容?

    目标

    如果外面不给传, 想给个默认显示内容

    语法&口诀

    夹着内容默认显示内容, 如果不给插槽slot传东西, 则使用夹着的内容在原地显示

    默认内容

    小结

    1. 如何给插槽设置默认显示内容?
      slot标签内写好默认要显示内容
    2. 什么时候插槽默认内容会显示?
      当使用组件并未给我们传入具体标签或内容时

    六、组件进阶 - 具名插槽

    思考

    问题1: 组件内有2处以上不确定标签怎么办?

    问题2: 能否给slot起个名字呢?

    目标

    当一个组件内有2处以上需要外部传入标签的地方

    传入的标签可以分别派发给不同的slot位置

    语法&代码

    v-slot一般用跟template标签使用 (template是html5新出标签内容模板元素, 不会渲染到页面上, 一般被vue解析内部标签)

    1. slot使用name属性区分名字
    2. template配合v-slot:名字来分发对应标签

    components/04/Pannel.vue - 留下具名slot

    views/04_UseSlot.vue使用

    
    
    

    小结

    1. 组件内多处不确定的标签如何做?
      slot占位, 给name属性起名字来区分
      template配合v-slot:name分发要替换的标签
    2. v-slot: 可以简化成什么?
      #

    七、组件进阶 - 作用域插槽

    思考

    问题: 使用插槽时, 想使用组件内的变量?

    目标

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

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

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

    语法&代码

    1. 子组件, 在slot上绑定属性和子组件内的值
    2. 使用组件, 传入自定义标签, 用template和v-slot="自定义变量名"
    3. scope变量名自动绑定slot上所有属性和值

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

    
    
    

    views/05_UseSlot.vue

    
    
    

    小结

    1. 作用域插槽什么时候使用?
      使用组件插槽技术时, 需要用到子组件内变量
    2. 作用域插槽使用口诀?
      子组件在slot身上添加属性和子组件的值
      使用组件处template配合v-slot=“变量名”(收集slot身上的所有属性和值)

    八、组件进阶 - 作用域插槽使用场景

    思考

    问题:作用域插槽具体使用场景有哪些呢?

    目标

    了解作用域插槽使用场景, 自定义组件内标签+内容

    案例: 封装一个表格组件, 在表格组件内循环产生单元格

    准备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标签

    学习笔记--Vue_第55张图片

    正确做法:

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

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

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

    小结

    我们为什么要使用作用域插槽?

    可以让组件更加灵活的适用于不同的场景和项目

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

    自定义指令

    一、自定义指令

    思考

    问题1: Vue内置指令不满足要求?

    问题2: 能否自己定义一些指令来使用?

    目标

    目标:获取标签, 扩展额外的功能

    局部注册

    语法

    export default {
        directives: {
            focus: {
                inserted(el){
                    el.focus()
                }
            }
        }
    }

    全局注册

    语法

    // 全局指令 - 到处"直接"使用
    Vue.directive("gfocus", {
      inserted(el) {
        el.focus() // 触发标签的事件方法
      }
    })

    全局注册自定义指令, 哪里都能用, 局部注册, 只能在当前vue文件里用

    小结

    我们为什么要自定义指令?

    在Vue内置指令满足不了需求时, 可以自己定义使用

    二、自定义指令传值

    思考

    问题: 指令能不能传值呢?

    目标

    目标: 使用自定义指令, 传入一个值

    语法

    // 目标: 自定义指令传值
    Vue.directive('color', {
      inserted(el, binding) {
        el.style.color = binding.value
      },
      update(el, binding) {
        el.style.color = binding.value
      }
    })

    你可能感兴趣的:(vue.js,学习,前端,1024程序员节)