vue这些原理你都知道吗?(面试版)

本文探讨Vue的原理,包括Vue与React的区别,new Vue的执行过程,响应式原理,计算属性,nextTick的工作机制,并深入分析Vue Router的本质和模板编译原理。适合面试复习与技术提升。
摘要由CSDN通过智能技术生成

前言

在之前面试的时候我自己也经常会遇到一些vue原理的问题, 我也总结了下自己的经常的用到的,方便自己学习,今天也给大家分享出来, 欢迎大家一起学习交流, 有更好的方法欢迎评论区指出, 后序我也将持续整理总结~

描述 Vue 与 React 区别

说明概念:
vue:是一套用于构建用户界面的渐进式框架,Vue 的核心库只关注视图层
react:用于构建用户界面的 JavaScript 库 声明式, 组件化

  1. 定位
  • vue 渐进式 响应式

  • React 单向数据流

  1. 写法
    vue:template,jsx
    react: jsx

  2. Hooks:vue3 和 react16 支持 hook

  3. UI 更新

  4. 文化
    vue 官方提供
    React 第三方提供,自己选择

整个 new Vue 阶段做了什么?

  1. vue.prototype._init(option)

  2. initState(vm)

  3. Observer(vm.data)

  4. new Observer(data)

  5. 调用 walk 方法,遍历 data 中的每个属性,监听数据的变化

  6. 执行 defineProperty 监听数据读取和设置

数据描述符绑定完成后,我们就能得到以下的流程图

在这里插入图片描述

  • 图中我们可以看出,vue 初始化的时候,进行了数据的 get\set 绑定,并创建了一个
  • dep 对象就是用来依赖收集, 他实现了一个发布订阅模式,完后了数据 data 的渲染视图 watcher 的订阅

参考 前端vue面试题详细解答

class Dep {
   
  // 根据 ts 类型提示,我们可以得出 Dep.target 是一个 Watcher 类型。
  static target: ?Watcher;
  // subs 存放搜集到的 Watcher 对象集合
  subs: Array<Watcher>;
  constructor() {
   
    this.subs = [];
  }
  addSub(sub: Watcher) {
   
    // 搜集所有使用到这个 data 的 Watcher 对象。
    this.subs.push(sub);
  }
  depend() {
   
    if (Dep.target) {
   
      // 搜集依赖,最终会调用上面的 addSub 方法
      Dep.target.addDep(this);
    }
  }
  notify() {
   
    const subs = this.subs.slice();
    for (let i = 0, l = subs.length; i < l; i++) {
   
      // 调用对应的 Watcher,更新视图
      subs[i].update();
    }
  }
}

描述 vue 的响应式原理

在这里插入图片描述

Vue 的三个核心类

  1. Observer :给对象的属性添加 getter 和 setter ,用于依赖收集派发更新
  2. Dep :用于收集当前响应式对象的依赖关系,每个响应式对象都有 dep 实例,dep.subs = watcher[],当数据发生变更的时候,会通过dep.notify()通知各个 watcher
  3. watcher:是一个中介,数据发生变化时通过 watcher 中转,通知组件 观察者对象,render watcher,computed watcher, user watcher
  • 依赖收集

  • 需要用到数据的地方,称为依赖

  • getter中收集依赖,在setter中触发依赖

  1. initState, 对 computed 属性初始化时,会触发computed watcher 依赖收集
  2. initState, 对监听属性初始化的时候,触发user watcher 依赖收集
  3. render,触发render watcher 依赖收集
  • 派发更新 Object.defindeProperty
  1. 组件中对响应式的数据进行了修改,会触发 setter 逻辑
  2. dep.notify()
  3. 遍历所有 subs,调用每一个 watcher 的 update 方法
    总结:
    当创建一个 vue 实例时, vue 会遍历 data 里的属性, Objeect.defineProperty 为属性添加 getter 和 setter 对数据的读取进行劫持
    getter:依赖收集
    setter:派发更新
    每个组件的实例都有对应的 watcher 实例

计算属性的原理

computed watcher 计算属性的监听器,格式化转换,求值等操作

computed watcher 持有一个 dep 实例,通过 dirty 属性标记计算属性是否需要重新求值
当 computed 依赖值改变后,就会通知订阅的 watcher 进行更新,对于 computed watcher 会将 dirty 属性设置为 true,并且进行计算属性方法的调用,

注意

  1. 计算属性是基于他的响应式依赖进行缓存的,只有依赖发生改变的时候才会重新求值
  2. 意义:比如计算属性方法内部操作非常频繁时,遍历一个极大的数组,计算一次可能要耗时 1s,如果依赖值没有变化的时候就不会重新计算

nextTick 原理

概念

nextTick 的作用是在下一次 DOM 更新循环结束后,执行延迟回调,nextTick 就是创建一个异步任务,要他等到同步任务执行完后才执行

使用

在数据变化后要执行某个操作,而这个操作依赖因数据的改变而改变 dom,这个操作应该放到 nextTick 中

vue2 中的实现

<template>
  <div>{
   {
    name }}</div>
</template>
<script>
export default {
     data() {
       return {
         name: ""
    }  },  mounted() {
       console.log(this.$el.clientHeight) // 0
    this.name = "better"
    console.log(this.$el.clientHeight) // 0
    this.$nextTick(() => {
         console.log(this.$el.clientHeight) // 18
    });  }};
</script>

我们发现直接获取最新的 DOM 相关的信息是拿不到的,只有在 nextTick 中才能获取罪行的 DOM 信息

原理分析

在执行 this.name = ‘better’ 会触发 Watcher 更新, Watcher 会把自己放到一个队列,然后调用 nextTick()函数

使用队列的原因:
比如多个数据变更更新视图多次的话,性能上就不好了, 所以对视图更新做一个异步更新的队列,避免重复计算和不必要的 DOM 操作,在下一轮时间循环的时候刷新队列,并执行已去重的任务(nextTick 的回调函数),更新视图

export function queueWatcher 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值