vue2总结

152 阅读5分钟

Vue2的响应式原理?

定义:响应式就是页面的模版内容能随着数据变化而重新渲染。 Vue2中,定义一个对象obj,使用Object.defineProperty对每个属性进行监听,当对属性进行读取时,会触发getter,对属性进行设置时,会触发setter

什么地方进行属性读取??

在Watcher读取数据的时候就触发了这个属性的监听getter,在getter里面就需要进行依赖收集,依赖存储的地方叫Dep,在Dep里把全局变量中的依赖进行收集,收集完毕就会把全局依赖变量设置为空,数据发生变化时,Dep把相关的Watcher执行一遍。

vue2中新增响应式属性要通过额外的 API?

object.defineProperty只会对属性进行检测,不会对对象进行监测。为了监测对象vue2创建了一个observer类。observer类的作用就是把一个对象全部转换成响应式对象。

object.defineProperty真的不能监听数组的变化么?

可以监听数组的变化,是因为数组是一个特殊的对象,它的下标可以看作是它的key,

Vue双向数据绑定的原理

  • vue接收一个模版和data参数
  • 会将data中的数据进行递归遍历,对每个属性执行Object.defineProperty,定义set和get函数。并对每个属性添加一个dep数组。
  • get执行时,会为调用的dom节点创建一个watcher存放在数组中
  • set执行时,重新赋值,调用dep数组的notify方法,通知所有使用该属性的watcher,更新对应dom的内容
  • 将模版加载到内存中,递归模版中的元素,检测到元素有v-开头的命令或{{}}的指令,就会从data中取对应的值去修改模版内容。该dom元素添加到该属性的dep数组中,实现数据驱动视图。
  • 处理v-model指令时,为该dom添加input事件(change),输入时就去修改对应的属性的值,实现页面驱动数据。
  • 模版与数据绑定后,将模版添加到真实的dom树中。

Vue事件绑定原理

Vue模版编译的原理

event-bus的原理

定义

EventBus是Vue提供的一个全局事件总线,实现原理是通过实例化一个vue实例作为事件中心,用来触发事件和监听事件。

实现方式
  • 创建一个新的Vue实例,作为事件中心,挂载到Vue的原型上,便于全局使用
import Vue from 'vue'
const EventBus = new Vue()
Vue.prototype.$bus = EventBus
  • 传递数据的组件中,通过$emit方法触发事件,并将数据作为参数传递
this.$bus.$emit('event1',data)
// event1是事件名称,data传递的数据
  • 接收数据的组件中,通过$on方法监听事件,并在回调函数中获取传递的数据
this.$bus.$on('event1',(data)=>{
   // 处理数据
})
使用event-bus时会出现内存泄漏问题

使用后要移除事件的监听

EventBus.$off()

Vuex的原理

原理解析
  • Vuex本质是一个对象
  • Vuex对象有两个属性,一个是install方法,一个是Store类
  • install方法的作用是将store这个实例挂载到所有组件上,(同一个store实例)
  • Store类拥有commit ,dispatch方法,Store类将用户传入的state包装成data,作为new Vue的参数,实现state值的响应式。
Vuex核心概念
  • state:存放状态数据的,数据是响应式的
  • getter:读取state中的数据
  • mutations:改变state中数据,修改数据是同步的
  • actions:提交mutations修改数据,修改数据是异步的
  • modules:使用modules将store分割成模块,每个模块中都有自己的state,getter,mutations,actions
注意点
  • state为什么不能在组件中修改,却只能通过mutations修改?
    • 保证数据的单向流动

vue.$set的原理

Vue中的scoped的原理

vue中的scoped是什么

vue文件中的style标签上,有一个特殊的属性:scoped。当一个style标签有scoped属性时,它的样式就只能作用于当前的组件。该属性,可以使组件之间的样式互相不污染,起到样式隔离,模块化的作用

scoped的原理
  • VueLoaderPlugin策略 VueLoaderPlugin先获取webpack原来的rules,然后创建pitcher规则,pi tcher中的pitcher-loader通过resourceQUERY识别引入文件的wuery带的关键字,进行loader解析 然后VueLoaderPlugin将进行clonedRule,重写resource和resourceQuery,使得loader能匹配上文件
  • 匹配文件后,vue-loader处理,根据文件路径和文件内容生成hash值,并赋给id,跟在文件参数后面
  • vue-loader会在css-loader前增加stylePostLoader,会给每个选择其增加属性[data-v-hash]
  • 开始渲染,template的render函数,vue-loader的normalizeComponent方法,判断vue文件中是否有scoped的style,并返回scopedId,在vnode渲染生成DOM时在dom元素上增加scopedId,也就是data-v-hash
父子组件是否受scoped的影响
  • 父组件未添加scoped,子组件未添加scoped。父组件的style生效(权重一样时)
  • 父组件未添加scoped,子组件添加scoped。子组件的style生效
  • 父组件添加scoped,子组件未添加scoped。子组件的style生效
  • 父组件添加scoped,子组件添加scoped。子组件的style生效
父组件样式覆盖子组件样式
  • 使用两个style,一个用于私有样式,一个用于共有样式
<!--共有样式-->
<style>
.content .button {
  color:red
}
</style>
<!--私有样式-->
<style scoped>
.content  {
  color:blue
}
</style>
  • 深度作用选择器
<style scoped>
<!--第一种-->
 .content /deep/ .button {
   color:red
 }
 <!--第二种-->
 .content ::v-deep .button {
   color:red
 }
</style>

nextTick的原理

Vue DOM更新是异步执行的,修改数据时,视图不会立即更新,而是会监听数据变化,并缓存在同一事件循环中,等同一数据循环中的所有数据变化完成之后,在统一进行视图更新,确保得到更新后的DOM,所以设置了Vue.nextTick()方法

Vue.mixin的原理

Vue.mixin的定义

混入(mixin)提供了一种非常灵活的方式,来分发Vue组件中的可复用功能。(抽离公共部分的作用)

全局混入
局部混入
使用时出现的问题?
  • 生命周期函数
    • 先执行mixin中生命周期函数中的代码,后执行组件内部的代码
  • data数据冲突
    • 组件中的data数据会覆盖mixin中的数据
  • 命名函数的冲突
    • 最终在组件中调用时,调用的是组件中的方法
mixin的优缺点
  • 优点
    • 可以提高代码的复用性
    • 无需传递状态
    • 维护方便,只需要修改一个地方
  • 缺点
    • 命名冲突
    • 滥用,后期难维护
    • 不能轻易的重复代码
    • 不好追溯源,排查问题稍显麻烦

computed的原理

diff算法原理