Vue2基础知识

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

随着Vue3的逐渐进入市场,让我们跟随着官网逐渐了解Vue2的基础吧


Vue2的特点

  1. 声明式(响应式)
  2. MVVM框架(M数据层<- ->VM虚拟DOM层<->V视图层)
  3. 组件化(支持自定义组件)
  4. 丰富的指令(DOM的抽象化)
  5. 基于选项(data,computed,methods,watch)

DOM与Vue2开发思想的区别

  • DOM开发思想:在交互事件中改变事件,使用DO选择器直接对节点进行DOM方法,改变视图
  • Vue2开发思想:在交互事件中改变事件,在data选项中声明一个合适的变量,通过这个声明式变量去改变,视图进行自动更新

指令

作用

用于视图节点上动态绑定变量,就是DOM功能的抽象,也是DOM操作

全部指令

  1. 文本指令(v-text,v-html,{{}},v-cloak,v-once)
  2. 动态属性指令(v-bind)可以换为:,属性有(style,class,value,title)
  3. 动态事件指令(v-on)可以换为@,事件修饰符(.enter,.stop,.prevent)
  4. 表单指令v-model,事件修饰符(.trim,.number,.lazy)
  5. 列表渲染指令(v-for)
  6. 条件渲染指令(v-if,v-else-if,v-else,v-show)
  7. 其他指令(v-pre,v-slot可以用#替换)

computed计算属性

作用

定义计算属性方法,在方法体中进行声明式变量的若干计算

优点

  1. 当指令的表达式复杂,可用computed进行优化,提升视图模板中代码的可读性,可维护性
  2. 进行缓存一个复杂的计算,避免组件更新时产生没有必要的性能损耗
  3. 计算属性默认是一个函数,表示get功能,为了支持set,要把计算属性写成对象结构xxx:{get,set}

watch监听器(侦听器)

作用

用于监听一个变量的变化,再做另外一件事

特点

当侦听器监听数据类型为引用数据类型时,只能监听一层,因为监听的越深,Vue在背后需要做的事情越多,对Vue来说是一种性能损耗,所以一般不要对一个引用数据类型监听,如果要监听可以针对某一节监听,具体方法为obj.key方法,如’info.child.age’(){}

响应式原理

在vue组件被创建时,在生命周期的第一阶段(创建阶段beforeCreate,created),Vue使用Object.defineProperty()data选项进行遍历劫持,并且添加get/set钩子,在生命周期第二阶段(挂载阶段beforeMount,mounted),指令第一次与声明式变量touch时,发生了依赖收集,再调用当前组件的watcher第一次更新DOM,DOM视图显现,当声明式变量发生改变时,Vue进行re-render,通知watcher更新DOM,这就是响应式

重要概念

  1. 劫持:使用Object.defineProperty()对data选项进行遍历并且添加getter,setter钩子
  2. touch:当指令第一次与声明式变量绑定时,第一次触发声明式变量的get钩子
  3. 依赖收集:第一次touch时,把当前声明式变量的更新方法添加到dep依赖数组
  4. watcher:跟声明式变量对应的DOM方法
  5. re-render:当声明式变量被set时,Vue通知Watcher更新DOM

组件基础

组件是HTML的扩展,使用粒度较小的HTML元素封装成粒度更大的标签(Vue组件),自定义组件技术是MVVM框架中最重要的技术之一,可以实现快速开发代码复用提升维护性

自定义组件

组件可以理解为一组选项构成的一个集合,封装组件时,可以使用到大多数的Vue选项属性比如data、template、methods

  1. 对组件来讲,最重要的选项为template,它用于指定组件的视图结构,在视图结构中你可以使用任意指令
  2. 对子组件来讲,可以通过props选项接收父组件传递过来的自定义属性,在组件内部用this访问
  3. 同样可以使用this.$emit(‘自定义事件’,数据)触发父组件给的自定义事件,并且回传数据给父组件

组件注册

  • 全局注册Vue.component(‘xx-yy’, ‘原材料选项’) 全局注册的组件,一次注册,在任何其它组件中都可以使用。
  • 局部注册components: { ‘xx-yy’: ‘原材料选项’ } 局部注册的组件,只能在当前组件作用域中使用。

注意:注册组件时,组件名称名称必须由多个单词用中划线连接。

关于组件间关系与通信

  • 约定:在MVVM框架,当我们谈论“组件”这个概念时,通常指是自定义组件当在A组件的视图结构中使用到了B组件,这就形成了组件关系(父子组件),那么A就是B组件的父组件,B就是A的子组件。
  • 通信:在Vue中,所谓“通信”就是组件之间的数据交互。父组件向子组件通信,使用自定义属性,在子组件使用props接收;子组件向父组件通信,使用自定义事件,在子组件中使用 this.$emit(‘自定义事件’, ‘数据’) 回传数据

组件化的三大技术

  • 自定义属性 <qf-score :num='num'></qf-score>
  • 自定义事件 <qf-score @change=''></qf-score>
  • 自定义插槽 <qf-score> <div #default></div> </qf-score>

深入学习v-model指令

  1. 组件中,v-model=‘num’ == :value=‘num’ + @input=‘num=$event’
  2. 在input中,对text,textarea 文本表单,v-model= :value + @input
  3. 在input选择框中,checkbox和radio选择框,v-model=:checked + @change
  4. 在input中下拉列表框中,select下拉框,v-model= :value +@change

生命周期

生命周期11个钩子

  1. 创建阶段:beforeCreate,Created
  2. 挂载阶段:beforeMount,Mounted
  3. 更改阶段:beforeUpdate,updated
  4. 销毁阶段:beforeDestroy,deatoryed
  5. 动态组件有关的两个特殊的钩子:activated(激活)、deactivated(休眠)
  6. 组件异常捕获有关的钩子:errorCaptured

生命周期流程

  1. beforeCreate

    1. 声明methods方法,声明生命周期钩子
  2. created (可调接口)

    1. 注入(injections)provide数据
    2. 进行响应式劫持、把data上数据遍历后放到this上
  3. beforeMount

    1. 通过el/$mount/template找视图模板
    2. template视图模板编译成render()(render方法是用于创建虚拟DOM的)
  4. mounted (调接口、开定时器、建立websocket长连接、echarts图表实例化、DOM/BOM操作)

    1. 创建**$el挂载节点,或者$mount**挂载
    2. 调用render()方法第一次生成虚拟DOM(Vnode是对真实视图结构的一种数据描述)
    3. Vue开始编译工作,循环递归,指令和声明式变量进行touch,依赖收集、通知Watcher第一次完成DOM渲染
  5. beforeUpdate

    1. 网页显示,当各种事件交互触发data变化时触发
  6. updated 在某些场景下,可以模拟出watch/$nextTick()的功能

    1. 再次调用render()方法生成新的虚拟DOM(现在就有了两个虚拟DOM)
    2. 执行patch运算(diff运算)找到两个虚拟DOM之间的最小差异(脏节点集合),通过一个队列进行异步更新
  7. beforeDestory 清除定时器、消除缓存

    1. 当调用**$destory()或者切换路由($route)**,即将进入销毁阶段
  8. destoryed

    1. 移除当前组件的Watcher(DOM将无法再更新了)
    2. 拆卸掉所有的子组件
    3. 移除事件监听器(watch等等)

Vue中内置组件

一共就5个内置组件分别为

  • slot
  • keep-alive
  • component
  • transition
  • transition-group

keep-alive动态组件

作用

keep-alive所包裹的组件不会被**‘销毁**’,你可以理解成是对组件的一种缓存

产生的生命周期钩子

被keep-alive所包裹的组件都会自动创建两个生命周期钩子:

  • activated 激活,当切换到被包裹的组件时就会出现一次激活钩子
  • deactivated 休眠,当切换走,被包裹的组件时就会出现一次休眠钩子

注意

​ 两组生命周期钩子的区别和使用场景:activated(执行多次)-mounted(执行一次),deactivated(执行多次)-beforeDestory(执行一次)

唯二的属性

  1. include 只包含 包含在incude数组中的组件不会‘destory’
  2. exclude 只不包含 不包含在exclude数组中的组件不会’destory’

component

作用

有种v-if的感觉,根据指定条件渲染目标组件,它的is属性等于哪个组件,就显示哪个组件

场景

它经常配合keep-alive一起使用

transition过渡动画

作用

是Vue内置的一种动画方式,可以很方便地为元素显示隐藏或者组件切换添加动画,本质是一种提升用户体验的优化

用法

把过渡动画抽象成两个过程(Enter进入动画、Leave离开动画),配合6个钩子使用。利用xx做例子

  • xx-enter
  • xx-enter-active
  • xx-enter-to
  • xx-leave
  • xx-leave-active
  • xx-leave-to

注意:

​ Vue过渡动画的终点是不会保留的,就相当于动画结束后元素的样式决定与class/style样式,在定义动画时,注意xx-enter-to和xx-leave这两个类名,最好配合UI的样式定义

使用第三方css动画库

如animate.css

  • 官网:https://animate.style/
  • 用法:安装或引入第三方css动画库,使用enter-active-class指定进入动画,使用leave-active-class指定离开动画

对多个元素执行动画时

  • 要给每个元素都加上唯一的key(key值不能重复),否则动画不生效
  • 使用mode指定多个元素显示与隐藏的先后顺序,通常mode='out-in’(离开动画先执行,再执行进入动画)

transition-group

作用

​ 一般用于给列表添加分组动画,可参照Vue官网

混入

作用

​ 用于向组件中混入可复用的选项(data,methods,生命周期钩子)

  • 全局混入:使用Vue.mixin({选项}),进行全局混入。所有组件都拥有了这些被混入的选项
  • 局部混入:使用**mixins:[{},{}]**选项进行局部混入,只有当前组件才有这些被混入的选项

注意:

​ 当一个组件同时有全局混入、局部混入、自有选项时,他们的优先级为

自有选项 > 局部混入 > 全局混入

结论:无论是全局混入还是局部混入,都解决的是选项复用问题

关于混入

  • 注意:工作中尽量不要使用全局混入,偶尔会用到局部混入
  • 缺点:当混入用得多了,选项就会变的‘来历不明’,代码不宜维护

过滤器

作用

​ 用于数据处理

  • 全局过滤器:使用Vue.filter(‘名称’,val=>{return newVal}) 定义,在任何组件中都可以直接使用
  • 局部过滤器:使用**filters:{}**定义,只能在当前组件中使用

注意1:

​ 过滤器只能用在**{{}}v-bind**中,不支持其他指令

注意2:

​ 过滤器还可以链式调用,像这样**{{num | f1 | f2}}**,过滤器是有顺序的

自定义指令

作用:

​ 在项目中有一些常用的DOM功能要复用时,建议封装成指令,这就是自定义指令,进行DOM功能的一种抽象封装

  • 全局指令:使用Vue.directive(‘指令名’,fn/{})定义全局指令,在任何组件中都能使用
  • 局部指令:使用**directives:{}**定义局部指令,只能在当前组件中使用

插件封装

作用

是一种更加高级的代码复用技术,可以以插件的方式为我们提供可复用的组件、混入、指令、过滤器、原型链API

说明

在Vue生态中,除了Vue本身,其他所有与Vue相关的第三方包,都是插件,都得以插件的方式进行集成

注意:

​ 以公司真实项目、优秀开源项目,你只要发现里面有好用的组件和指令,都可以搬到自己的review中,以便未来复用

封装Vue插件方法

  1. const Plugin={install(val){}}
  2. const Plugin=function(Vue){}
  3. 导入插件,Vue.use(Plugin)

两个重要的API

Vue.nextTick()/this.$nextTick()

事实:

set操作,代码确实是同步的,但是set行为是异步的;set操作修改声明变量,触发re-render生成新的虚拟DOM,进一步执行diff运算,找到脏节点集合,交给Vue背后的更新队列去执行循环更新DOM

作用:

这么描述一个场景,我们set操作data(更新DOM),你希望访问这个DOM的最新状态时,使用this.$nextTick(handler)

什么是nextTick,怎么用?
  • 在更新队列中每一个更新任务都是一个更新单元,nextTick表示下一个更新单元(更新周期)
  • 在某种程度(场景)上,可以使用updated()来代替;原则上建议使用nextTick(),因为nextTick只在局部,updated是全局的

this.$forceUpdate()

事实:

​ Vue响应式是有缺陷的,在Vue应用中,如果声明式变量是引用数据类型时,当进行set操作这些复杂的引用数据类型时,视图会出现不更新的情况

解决方案

​ set操作完成后,立即调用**this.$forceUpdate()强调更新**(强制re-render),

​ 但,有时候this.$forceUpdate()也无法解决上述问题,这个时候我们对set操作的变量进行一次深拷贝还在利用Lodash库中的**_.cloneDepp**()

组件通信

什么是通信

通信是组件或者模块之间的数据交互,多重通信就形成了数据流,数据流管理的优劣决定了产品能否上线,通常数据流(通信)越混乱,代码越难维护

Vue中常见的通信方案
  1. 父子组件通信:父传子使用自定义属性(props),子传父使用自定义事件($emit())。
  2. 状态提升:当兄弟组件之间需要共享数据时,我们通常的做法是把这个数据定义它们的共同的父组件中,再通过自定义属性实现数据共享
  3. provide/inject:这是在组件树中,自上而下的一种数据通信方案,也就是说只能父级组件中向后代组件传递。需要注意的是,当provide提供动态数据(声明式变量)时,动态数据发生变化,后代组件们不会自动更新。这是为什么呢?你自己从生命周期流程的角度去思考。
  4. ref通信:ref是Vue内置的一个属性,每一个HTML元素或组件都有这个属性;ref作用在HTML元素上得到DOM实例,ref作用在组件上得到组件实例。使用ref访问组件实例,进一步可以访问组件中的数据和方法。(说明:ref是一种快速的DOM的访问方式,当然ref也可作用在组件上得到组件实例。这些ref得到的DOM实例或组件实例,使用this.$refs来访问它们。ref尽量少用,除非某些难搞的需求。)
  5. 插槽通信:借助组件实现从子组件向父组件传递数据,借助this.$slots访问父组件中的插槽实例。(在自定义组件中使用this.$slots访问父组件给的插槽实例;在父组件插槽中使用**#default=‘scoped’**访问子组件回传的数据。这种通信在组件库中、工作中,非常常见!)
  6. $parent/$children:借助 p a r e n t / parent/ parent/children可以实现,在任一组件中访问组件树中的其它任意组件实例,可以做到在组件中随意穿梭。( p a r e n t 表示的是当前组件的父组件实例, parent表示的是当前组件的父组件实例, parent表示的是当前组件的父组件实例,children表示的是当前组件的子组件们。)
  7. $attrs/$listeners:借助$attrs可访问父组件传递过来的自定义属性(除了class和style外),借助$listenrs可以访问父组件给的自定义事件。在某些场景下,$attrs/$listeners可以替代props/$emit()这种通用的通信方案
  8. 事件总线:借助于Vue内置的事件系统($on/$emit/$off/$once)实现“订阅-发布”式的通信,这种通信方式是一种与组件层级无关的“一对多”的通信。(工作中很少用,一些特殊的Vue项目才用得到事件总线。)
  9. Vuex通信:这是Vue架构中终极的通信方案,也是Vue架构中用的最多的一种通信方案。

总结

根据Vue2官网所示,并且进行简单概括了一些,可能也属于精华吧,就这么多了,还有很多认为不太重要的就没有做记录。学习Vue2最好还是随着官网学习,让我们加油吧!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值