vue相关知识汇总

前言

最近复盘了一下vue相关知识,对vue有了进一步的认识了解(数据绑定、响应式原理、diff算法、一些工作中常用的属性方法是具体怎么实现等),空余时间整理了一下分享给大家,希望对你有所帮助~~~

vue 的优点

  1. 低耦合,视图(View)可以独立于 Model 变化和修改,一个 ViewModel 可以绑定到不同的"View"上,当 View 变化的时候 Model 可以不变,当 Model 变化的时候 View 也可以不变
  2. 可重用性,你可以把一些视图逻辑放在一个 ViewModel 里面,让很多 view 重用这段视图逻辑独立开发、可测试
  3. 独立性,开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计可测试,界面素来是比较难于测试的,而现在测试可以针对 ViewModel 来写

vue 的双向数据绑定的原理

在vue2.0单中,实现数据双向绑定时使用了Object.defineProperty() 这个方法重新定义了对象获取 get 和设置属性 set 的操作来实现
vue3.0 中用 proxy 替换 Obiject.defineProperty()

vue响应式原理

当对象传入vue实例作为data对象时,首先被vue遍历所有属性,调用Object.defineProperty设置为 getter 和setter,每个组件都有一个watcher对象,在组件渲染的过程中,把相关的数据都注册成依赖,当数据发生setter变化时,会通知触发watcehr,从而更新相关联的组件达到数据变化驱动试图更新。

1)对象内部通过defineReactive方法,使用Object.defineProperty() 监听数据属性的 get 来进行数据依赖收集,再通过 set 来完成数据更新的派发;数组则通过重写数组方法来实现的。扩展它的 7 个变更⽅法,通过监听这些方法可以做到依赖收集和派发更新;( push/pop/shift/unshift/splice/reverse/sort )多层对象是通过递归来实现劫持,vue3中是使用 proxy来实现响应式数据内部依赖收集是怎么做到的,每个属性都拥有自己的dep属性,存放他所依赖的 watcher,当属性变化后会通知自己对应的 watcher去更新。
响应式流程:
1、defineReactive 把数据定义成响应式的;
2、给属性增加一个 dep,用来收集对应的那些watcher;
3、等数据变化进行更新dep.depend() // get 取值:
进行依赖收集dep.notify() // set 设置时:
通知视图更新这里可以引出性能优化相关的内容:
1)对象层级过深,性能就会差。
2)不需要响应数据的内容不要放在data中。
3)object.freeze() 可以冻结数据。

vue2.0、3.0 Diff 算法

diff 算法过程:

  1. 同级比较,再比较子节点
  2. 先判断一方有子节点一方没有子节点的情况(如果新的children没有子节点,将旧的子节点移除)
    比较都有子节点的情况(核心diff)
  3. 比较都有子节点的情况(核心diff)
  4. 递归比较子节点
  5. 正常Diff两个树的时间复杂度是O(n^3) ,但实际情况下我们很少会进行跨层级的移动DOM,所以Vue将Diff进行了优化,从O(n^3) -> O(n),只有当新旧children都为多个子节点时才需要用核心的Diff算法进行同层级比较。
    6.vue2 的核心Diff算法采用了双端比较的算法,同时从新旧children的两端开始进行比较,借助key值找到可复用的节点,再进行相关操作。相比React的Diff算法,同样情况下可以减少移动节点次数,减少不必要的性能损耗,更加的优雅
    Vue3 借鉴了 ivi算法和 inferno算法
    在创建VNode时就确定其类型,以及在mount/patch的过程中采用位运算来判断一个VNode的类型,在这个基础之上再配合核心的Diff算法,使得性能上较Vue2.x有了提升

proxy 相比于 defineProperty 有哪些优势 / 为什么要在vue3 中替换 Obiject.defineProperty ?

Obiject.defineProperty 是无法监控到数组下标的变化,导致我们需要直接通过数组下标给数组设置值,不会实时响应。Obiject.defineProperty 它只会去劫持对象的属性,因此我们需要对每个对象的每个属性都去遍历。在2.0当中,它是通过 递归 + 遍历data对象来实现对数据的监控,若我们的属性值也是对象的,那么就需要深度遍历,很显然,能劫持一个完整的的对象才是更好的选择。proxy 可以去劫持整个对象 并且返回一个新的对象。

什么是 Vue.nextTick() ?

下次 DOM 更新循环结束之后执行延迟回调;再修改数据之后立即使用这个方法,获取更新后的 DOM;由上所述 所以就衍生出了这个获取更新后 DOM 的 vue方法,所以放在 Vue.nextTick() 回调函数中所执行的是会对 DOM 进行操作的 js 代码,Vue.nextTick() 时将函数延迟到下次dom 更新后数据后调用 ,简单来说就是当我们的数据更新,dom渲染后,激动执行该函数

什么场景下我们需要去使用Vue.nextTick()?

  1. vue生命周期 created 中进行 Dom 操作 一定要 放在 Vue.nextTick() 的回调函数中,因为在created() 钩子函数执行时 Dom 并未进行任何渲染,在此我们对Dom进行操作无异于徒劳,所此在此钩子函数中 我们一定要将我们 DOM 操作的 js 代码放进 Vue.nextTick()
  2. 当在我们项目中想在改变 DOM 元素的数据后基于新的 dom 做点什么,对新 DOM 一系列的 js 操作都需要放进 Vue.nextTick()的回调函数中;通俗的理解就是:更改数据后,你想立即使用 js 操作新的视图的时候需要使用它
  3. 3.当我们在使用某个第三方插件时 ,希望在 vue 生成的某些 dom 动态发生变化时重新应用该插件,也会用到该方法,这时候就需要在 $nextTick 的回调函数中执行重新应用插件的方法

计算属性、方法、watch的区别?

  1. 计算属性是基于数据的依赖缓存,数据发生变化,缓存才会发生变化,如果数据没有发生变化,调用计算属性直接调用的是存储的缓存值;
  2. 方法每次调用都会重新计算;所以可以根据实际需要选择使用,如果需要计算大量数据,性能开销比较大,可以选用计算属性,如果不能使用缓存可以使用方法;
  3. watch是用来监测数据的变化,和计算属性相比,是watch没有缓存,但是一般想要在数据变化时响应时,或者执行异步操作时,可以选择watch

vuex 工作原理详解

  1. vuex 整体思想诞生于 flux, 可其的实现方式完全使用了 vue 自身的响应式设计,依赖监听、依赖收集都属于 vue 对 对象 Property set get 方法的代理劫持。vuex 中的 store 本质就是没有 template 的隐藏着的 vue 组件;
  2. vuex生成了一个 store 实例,并且把这个实例挂在了所有的组件上,所有的组件引用的都是同一个store实例。 store实例上有数据、有方法,方法改变的都是store实例上的数据。由于其他组件引用的是同样的实例,所以一个组件改变了store上的数据, 导致另一个组件上的数据也会改变,就像是一个对象的引用。

new Vue() 发生了什么?

new Vue()是创建Vue实例,它内部执行了根实例的初始化过程。
c h i l d r e n , children, childrenrefs, s l o t s , slots, slotscreateElement等实例属性的方法初始化
自定义事件处理
数据响应式处理
生命周期钩子调用
可能的挂载new Vue()创建了根实例并准备好数据和方法,未来执行挂载时,此过程还会递归的应用于它的子组件上,最终形成一个有紧密关系的组件实例树。

vue3 相对于 vue2 新特性、优点

  1. performance: 性能比vue2.x块1.2~2倍;
  2. Tree shaking support: 按需编译,体积比vue2.x更小;
  3. Composition API: 组合API(类似React Hooks);
  4. Better TypeScript support: 更好的 ts 支持;
  5. Custom Render API: 暴露了自定义渲染的API ;
  6. Fragment, Teleport(Protal): 更先进的组件 ;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值