Vue框架

一、Vue框架概述

1. vue框架的介绍

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

Vue 是一套用于构建用户界面的渐进式框架. 与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。

Vue.js 是前端的主流框架之一,和 Angular.js、React.js 一起,并成为前端三大主流框架

官网地址: Vue.js - 渐进式 JavaScript 框架 | Vue.jsVue.js - 渐进式的 JavaScript 框架https://cn.vuejs.org/ (作者: 尤雨溪)

2. vue的特点

  • 渐进式

  • 声明式渲染

  • 数据驱动视图 (响应式)

  • 极少的去写DOM操作相关代码

  • 双向绑定

  • 组件系统

  • 不兼容IE8及以下浏览器

3. Vue的优点

1.体积小 
2.更高的运行效率
3.双向数据绑定,简化 Dom 操作
通过 MVVM 思想实现数据的双向绑定
4 生态丰富、学习成本低
市场上拥有大量成熟、稳定的基于 vue.js 的 ui 框架、常用组件 来即用实现
快速开发 对初学者友好、入门容易、学习资料多.

二、@vue/cli脚手架

1. @vue/cli 脚手架介绍

      @vue/cli是Vue官方提供的一个全局模块包(得到vue命令), 此包用于创建脚手架项目

脚手架是为了保证各施工过程顺利进行而搭设的工作平台

@vue/cli的好处

                             开箱即用

                             0配置webpack

                             babel支持

                             css, less支持

                             开发服务器支持

2. @vue/cli安装

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

  • (1)全局安装命令

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

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

  • (2)查看vue脚手架版本

    vue -V

Vue框架_第1张图片

总结: 如果出现版本号就安装成功, 否则失败

3. @vue/cli 创建项目启动服务

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

(1)创建项目

# vue和create是命令, vuecli-demo是文件夹名
vue create vuecli-demo

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

(2)选择模板和包管理器, 等待脚手架项目创建完毕

a. 选择预置版本为vue2还是vue3(可以上下箭头选择, 弄错了ctrl+c重来)

Vue框架_第2张图片

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

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

Vue框架_第3张图片

 d. cd进入项目下, 启动内置的webpack本地热更新开发服务器
cd vuecil-demo
​
npm run serve
# 或
yarn serve
只要看到绿色成功了(底层node+webpack热更新服务)

Vue框架_第4张图片

 e. 如果未自动弹出浏览器, 手动打开浏览器输入上述地址

Vue框架_第5张图片

4.  @vue/cli 目录和代码分析

Vue框架_第6张图片

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    # 项目包版本锁定和缓存地址

主要文件及含义

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

5. @vue/cli 项目架构了解

Vue框架_第7张图片

 Vue框架_第8张图片

6. @vue/cli 自定义配置

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

src并列处新建vue.config.js

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

7. eslint了解

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

(1)如果写代码违反了eslint的规则-报错

演示: 在main.js中随便定义变量 – 不使用 – 观察eslint报错

Vue框架_第9张图片

 (2)处理eslint代码检查

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

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

Vue框架_第10张图片

8. @vue/cli 单vue文件讲解

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

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

template里只能有一个根标签

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

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

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

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

单vue文件好处?
             独立作用域, 不再担心变量重名问题

9. @vue/cli 欢迎界面清理

(1)assets 和 components 文件夹下的一切都删除掉 (不要默认的欢迎页面)
(2)src/App.vue默认有很多内容, 可以全部删除留下template和script和style的框

 Vue框架_第11张图片

三、vue基础-MVVM设计模式

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

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

  • MVVM,一种软件架构模式,决定了写代码的思想和层次

    • M: model数据模型 (data里定义)

    • V: view视图 (html页面)

    • VM: ViewModel视图模型 (vue.js源码)

  • MVVM通过数据双向绑定让数据自动地双向同步 不再需要操作DOM

    • V(修改视图) -> M(数据自动同步)

    • M(修改数据) -> V(视图自动同步)

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

2. 在vue中,通过数据驱动视图,不再需操作DOM,而是如何操作数据

Vue框架_第12张图片

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

mvvm和mvc区别是什么?

MVC: 也是一种设计模式, 组织代码的结构, 是model数据模型, view视图, Controller控制器, 
在控制器这层里编写js代码, 来控制数据和视图关联

MVVM: 即Model-View-ViewModel的简写。即模型-视图-视图模型, VM是这个设计模式的核心,
 连接v和m的桥梁, 内部会监听DOM事件, 监听数据对象变化来影响对方. 我们称之为数据绑定

四、vue基础

1. 插值表达式

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

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

语法: {{ 表达式 }}

msg和obj是vue数据变量
要在js中data函数里声明

Vue框架_第13张图片





 总结: dom中插值表达式赋值, vue的变量必须在data里声明

Vue框架_第14张图片

 2. vue指令-v-bind

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

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

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

Vue框架_第15张图片

  • 语法:v-bind:属性名="vue变量"

  • 简写::属性名="vue变量"


我是a标签

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

3. vue指令-v-on

目标: 给标签绑定事件

  • 语法

    • v-on:事件名="要执行的==少量代码=="

    • v-on:事件名="methods中的函数"

    • v-on:事件名="methods中的函数(实参)"

  • 简写: @事件名="methods中的函数"


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

总结: 常用@事件名, 给dom标签绑定事件, 以及=右侧事件处理函数

练习-翻转世界

Vue框架_第16张图片

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

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



4. vue指令-v-on事件对象

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

  • 语法:

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

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

5. vue指令-v-on修饰符

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

  • 语法:

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

      • .stop - 阻止事件冒泡

      • .prevent - 阻止默认行为

      • .once - 程序运行期间, 只触发一次事件处理函数

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

6. vue指令-v-on按键修饰符

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

  • 语法:

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

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

更多修饰符https://cn.vuejs.org/v2/guide/events.html#%E6%8C%89%E9%94%AE%E4%BF%AE%E9%A5%B0%E7%AC%A6

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

7. vue指令 v-model

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

  • 语法: v-model="vue数据变量"

  • 双向数据绑定

    • 数据变化 -> 视图自动同步

    • 视图变化 -> 数据自动同步

Vue框架_第17张图片

  • 演示: 用户名绑定 - vue内部是MVVM设计模式

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

8. vue指令 v-model修饰符

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

  • 语法:

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

      • .number 以parseFloat转成数字类型

      • .trim 去除首尾空白字符

      • .lazy 在change时触发而非inupt时

Vue框架_第18张图片

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

9. vue指令 v-text和v-html

目的: 更新DOM对象的innerText/innerHTML

  • 语法:

    • v-text="vue数据变量"

    • v-html="vue数据变量"

  • 注意: 会覆盖插值表达式

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

10. vue指令 v-show和v-if

目标: 控制标签的隐藏或出现

  • 语法:

    • v-show="vue变量"

    • v-if="vue变量"

  • 原理

    • v-show 用的display:none隐藏 (频繁切换使用)

    • v-if 直接从DOM树上移除

  • 高级

    • v-else使用

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

案例-折叠面板

Vue框架_第19张图片

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

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

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




11. vue指令-v-for

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

  • 语法

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

    • v-for="值 in 目标结构"

  • 目标结构:

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

  • 注意:

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

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

为什么避免v-for和v-if在一起使用

​	Vue 处理指令时,v-for 比 v-if 具有更高的优先级, 虽然用起来也没报错, 
但是性能不高, 如果你有5个元素被v-for循环, v-if也会分别执行5次.

 练习-购物车

Vue框架_第20张图片

目标: 完成商品浏览和删除功能, 当无数据给用户提示

  • 需求1: 根据给的初始数据, 把购物车页面铺设出来

  • 需求2: 点击对应删除按钮, 删除对应数据

  • 需求3: 当数据没有了, 显示一条提示消息

    
    
    
    
    
    

    12. vue基础 v-for更新监测

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

    情况1: 数组翻转

    情况2: 数组截取

    情况3: 更新值

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

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

push()

pop()

shift()

unshift()

splice()

sort()

reverse()

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

slice()

filter()

concat()

Vue框架_第21张图片  

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

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

Vue框架_第22张图片

13. vue基础 v-for就地更新

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

详解v-for就地更新流程

Vue框架_第23张图片

 这种虚拟DOM对比方式(同级对比,标签与标签对比,相同则复用), 可以提高性能 - 但是还不够高

14. vue基础_虚拟dom

(1)真实DOM:在document对象上, 渲染到浏览器上显示的标签

Vue框架_第24张图片

Vue框架_第25张图片

 (2)虚拟DOM:本质是保存节点信息, 属性和内容的一个JS对象

Vue框架_第26张图片

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

Vue框架_第27张图片

    b.  内存中生成一样的虚拟DOM结构(本质是个JS对象)

(3)vue数据更新

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

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

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

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

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

Vue框架_第28张图片

15. vue基础_diff算法

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

(1)同级比较-根元素变化-整个dom树删除重建

Vue框架_第29张图片

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

旧虚拟DOM

   

123

新虚拟DOM

       
  • 123

(2)同级比较-根元素不变-属性改变更新属性

Vue框架_第30张图片

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

旧虚拟DOM

   

123

新虚拟DOM

   

123

16. vue基础_diff算法-key

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

(1)无key - 就地更新(最大限度尝试就地修改/复用相同类型元素)

Vue框架_第31张图片

 Vue框架_第32张图片

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

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

Vue框架_第33张图片

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

(2)有key - 值为索引(还是就地更新 )

有key属性, 基于key的来比较新旧虚拟DOM, 移除key不存在元素

        先产生新旧虚拟DOM, 根据key比较, 因为新旧虚拟DOM对比, key存在就复用此标签更新内容, 如果不存在就直接建立一个新的,因此还是就地更新

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

Vue框架_第34张图片

 v-for先循环产生新的DOM结构, key是连续的, 和数据对应

 然后比较新旧DOM结构, 找到区别, 打补丁到页面上

 最后补一个li, 然后从第二个往后, 都要更新内容

(3)有key - 值为id

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

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

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

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

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




先产生新旧虚拟DOM, 根据key比较

Vue框架_第35张图片

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

(4)有key和无key小结

Vue框架_第36张图片

 Vue框架_第37张图片

17. vue基础_动态class

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

  • 语法:

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

Vue框架_第38张图片

总结: 就是把类名保存在vue变量中赋予给标签

18. vue基础-动态style

目标: 给标签动态设置style的值

  • 语法

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

    • Vue框架_第39张图片

总结: 动态style的key都是css属性名

Vue框架_第40张图片

案例-品牌管理

Vue框架_第41张图片

  • 需求1: 把默认数据显示到表格上

  • 需求2: 注意资产超过100的, 都用红色字体标记出来

  • 实现数据增删

细节:

① 先铺设静态页面 

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

   bootstrap, 工程化开发, 模块化用npm/yarn下载引入使用

arn add bootstr

   在main.js - 引入bootstrap  

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

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

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





五、vue过滤器

1. vue过滤器-定义使用

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

Vue框架_第42张图片

 例子:

  • 全局定义字母都大写的过滤器

  • 局部定义字符串翻转的过滤器

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

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

2. vue过滤器-传参和多过滤器

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

  • 语法:

    • 过滤器传参: vue变量 | 过滤器(实参)

    • 多个过滤器: vue变量 | 过滤器1 | 过滤器2

Vue框架_第43张图片

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

Vue框架_第44张图片

3. 案例-品牌管理(时间格式化)

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

           moment官网文档: Moment.js 中文网 | 开发文档

yarn add moment

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

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

{{ obj.time | formatDate }}

六、vue计算属性

1. vue计算属性-computed

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

语法:

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

Vue框架_第45张图片

需求:

  • 需求: 求2个数的和显示到页面上

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

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

2. vue计算属性-缓存

目标: 计算属性是基于它们的依赖项的值结果进行缓存的,只要依赖的变量不变, 都直接从缓存取结果

Vue框架_第46张图片

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

3. vue计算属性-完整写法

目标: 计算属性也是变量, 如果想要直接赋值, 需要使用完整写法

语法:

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

需求:

  • 计算属性给v-model使用

页面准备输入框

总结: 想要给计算属性赋值, 需要使用set方法

Vue框架_第47张图片

4. 案例-品牌管理(总价和均价)

目标: 基于之前的案例, 完成总价和均价的计算效果

此处只修改了变化的代码


     统计:
     总价钱为: {{ allPrice }}
     平均价: {{ svgPrice }}

​

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

5. 案例-全选反选

Vue框架_第48张图片



七、 vue侦听器

1. vue侦听器-watch

目标: 可以侦听data/computed属性值改变

语法:

watch: {
    "被侦听的属性名" (newVal, oldVal){
        
    }
}

完整例子代码:

总结: 想要侦听一个属性变化, 可使用侦听属性watch

2. vue侦听器-深度侦听和立即执行

目标: 侦听复杂类型, 或者立即执行侦听函数

  • 语法:

    watch: {
        "要侦听的属性名": {
            immediate: true, // 立即执行
            deep: true, // 深度侦听复杂类型内变化
            handler (newVal, oldVal) {
                
            }
        }
    }

完整例子代码:

总结: immediate立即侦听, deep深度侦听, handler固定方法触发

3. 案例-品牌管理(数据缓存)

目标: 侦听list变化, 同步到浏览器本地

  • 需求: 把品牌管理的数据实时同步到本地缓存

分析:

① 在watch侦听list变化的时候, 把最新的数组list转成JSON字符串存入到localStorage本地

② data里默认把list变量从本地取值, 如果取不到给个默认的空数组

效果:

新增/删除 – 刷新页面 – 数据还在

八、vue组件

1. vue组件_概念

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

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

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

Vue框架_第49张图片

2. vue组件_基础使用

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

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

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

步骤:

(1)创建组件 components/Pannel.vue

封装标签+样式+js - 组件都是独立的, 为了复用





 (2)注册组件: 创建后需要注册后再使用

全局 - 注册使用

全局入口在main.js, 在new Vue之上注册

语法:

import Vue from 'vue'
import 组件对象 from 'vue文件路径'

Vue.component("组件名", 组件对象)

main.js

// 目标: 全局注册 (一处定义到处使用)
// 1. 创建组件 - 文件名.vue
// 2. 引入组件
import Pannel from './components/Pannel'
// 3. 全局 - 注册组件
/*
  语法: 
  Vue.component("组件名", 组件对象)
*/
Vue.component("PannelG", Pannel)

全局注册PannelG组件名后, 就可以当做标签在任意Vue文件中template里用

单双标签都可以或者小写加-形式, 运行后, 会把这个自定义标签当做组件解析, 使用组件里封装的标签替换到这个位置



局部 - 注册使用

语法:

import 组件对象 from 'vue文件路径'
​
export default {
    components: {
        "组件名": 组件对象
    }
}

任意vue文件中中引入, 注册, 使用

(3)组件使用总结

(1)(创建)封装html+css+vue到独立的.vue文件中

(2)(引入注册)组件文件 => 得到组件配置对象

(3)(使用)当前页面当做标签使用

4. vue组件-scoped作用

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

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

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

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

App.vue中使用并传入数据(引入组件, 注册组件, 使用组件, 传值进去)

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

(2)vue组件通信_父向子-配合循环

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

数据

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

2. 单向数据流

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

在vue中需要遵循单向数据流原则

父组件的数据发生了改变,子组件会自动跟着变

子组件不能直接修改父组件传递过来的props, props变量本身是只读不能重新赋值

注意:
      父组件传给子组件的是一个对象,子组件修改对象的属性,是不会报错的,
      对象是引用类型, 互相更新

Vue框架_第51张图片

原因: 子组件修改, 不通知父级, 造成数据不一致性

        第一个MyProduct.vue内自己修改商品价格为5.5, 但是App.vue里原来还记着18.8 - 数据 不一致了

总结: props变量本身是不能重新赋值的

3. vue组件通信_子向父

目标: 从子组件把值传出来给外面使用

语法:

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

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

Vue框架_第52张图片

 Vue框架_第53张图片 

(1)父组件内, 绑定自定义事件和事件处理函数
          @自定义事件名="父methods里函数名"

  App.vue





(2)子组件内, 恰当的时机, 触发父给我绑的自定义事件, 导致父methods里事件处理函数执行

Vue框架_第54张图片

 components/MyProduct_sub.vue





总结: 父自定义事件和方法, 等待子组件触发事件给方法传值

3. vue组件通信-EventBus

目标: 常用于跨组件通信时使用

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

两个组件的关系非常的复杂,通过父子组件通讯是非常麻烦的。

这时候可以使用通用的组件通讯方案:事件总线(event-bus)

Vue框架_第55张图片

Vue框架_第56张图片

Vue框架_第57张图片  

Vue框架_第58张图片

       总结: 空的Vue对象, 只负责$on注册事件, $emit触发事件, 一定要确保$on先执行

十、vue的生命周期

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

Vue_生命周期

Vue框架_第59张图片

1. 钩子函数

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

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

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

分类: 4大阶段8个方法

  • 初始化

  • 挂载

  • 更新

  • 销毁

阶段 方法名 方法名
初始化 beforeCreate created
挂载 beforeMount mounted
更新 beforeUpdate updated
销毁 beforeDestroy destroyed

官网文档https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA

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

Vue框架_第60张图片

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框架_第61张图片

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


App.vue - 引入使用



3. 挂载阶段

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

含义讲解:

1.template选项检查

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

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

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

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

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

5.真实DOM挂载完毕

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

​​​​​​​

Vue框架_第62张图片



4. 更新阶段

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

含义讲解:

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

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

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

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

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

​​​​​​​Vue框架_第63张图片

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

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



5. 销毁阶段

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

含义讲解:

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

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

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

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

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

Vue框架_第64张图片

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

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




十一、$refs和$nextTick

1.  $refs-获取DOM

目标: 利用 ref 和 $refs 可以用于获取 dom 元素

components/More.vue





总结: 通过id / ref, 都可以获取原生DOM标签

2. $refs-获取组件对象

目标: 获取组件对象, 调用组件里方法

components/Child/Demo.vue

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

总结: ref定义值, 通过$refs.值 来获取组件对象, 就能继续调用组件内的变量

 3.  $nextTick使用

Vue更新DOM-异步的

目标: 点击count++, 马上通过"原生DOM"拿标签内容, 无法拿到新值

components/Move.vue - 继续新增第三套代码

总结: 因为DOM更新是异步的

4.  $nextTick使用场景

Vue框架_第65张图片

目标: 点击搜索按钮, 弹出聚焦的输入框, 按钮消失

Vue框架_第66张图片components/Tick.vue

5. 组件name属性使用

目标: 可以用组件的name属性值, 来注册组件名字

问题: 组件名不是可以随便写的?

答案: 我们封装的组件-可以自己定义name属性组件名-让使用者有个统一的前缀风格

components/Com.vue

App.vue - 注册和使用

你可能感兴趣的:(vue.js,前端,javascript)