2024前端面试题总结之 vue2 vue3

432 阅读4分钟

vue2

vue2官方文档

生命周期图

第一张当然是官网的生命周期图 生命周期 beforeCrated, created, beforeMounted, mounted, beforeDestroy, destroyed, beforeUpdated updated, actived, deactived

image.png

双向绑定原理

  • JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setterObject.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。

  • 这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更

  • 每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,关联的组件重新渲染。

image.png

数据响应式更新

  • 数据对象上更新数据 需要使用 Vue.set(data, property, value)
  • 数组数据的更新使⽤了函数劫持的⽅式,重写了数组的⽅法,Vue将data中的数组进⾏了原型方法重写,指 向了⾃⼰定义的数组原型⽅法。当调⽤数组api时,可以通知依赖更新。如果数组中 包含着引⽤类型,会对数组中的引⽤类型再次递归遍历,实现了监测数组变化

vue3

vue3官方文档

ref 和 reactive

  • ref 可以声明任何数据
  • reactive 只能声明对象
    为什么会出现这种情况呢,原因是 Proxy 无法对原始数据类型代理,运行了上述代码,会发现控制台正常输出了 setget。如果我们将obj改成原始数据类型,并再次测试,你会发现控制台输出了报错信息。
// 定义一个对象
let obj = { name: "juejin" };
// 将对象传入Proxy中,并传入处理器对象来重写它的get和set方法
const proxyObj = new Proxy(obj, {
  get(target, property, receiver) {
    // 获取数据的时候输出‘get’
    console.log("get");
  },
  set(target, property, value, receiver) {
    // 设置数据的时候输出‘set’
    console.log("set");
    return "set";
  },
});

proxyObj.name = '1';
proxyObj.name

然而,转变思路 我把简单数据改为 { value } 是不是就可以了

function ref(value) {
  // 将传入的值存在obj中
  const obj = { value };

  // 返回一个Proxy代理
  return new Proxy(obj, {
    // 获取数据
    get(target, property, receiver) {
      console.log("get");
      return target.value;
    },

    
    set(target, property, value, receiver) {
      target.value = value;

      console.log("set");
      return "set";
    },
  });
}

// 测试
const num = ref(0);
num.value; // 输出'get'
num.value = 1; // 输出'set'

watch和watchEffect的区别

  • watchwatchEffect 都是监听器,watchEffect 是一个副作用函数。它们之间的区别有:

  • watch :既要指明监视的数据源,也要指明监视的回调

  • watchEffect 可以自动监听数据源作为依赖。不用指明监视的具体数据,监视的回调中用到的数据。

  • watch 可以访问改变之前和之后的值,watchEffect 只能获取改变后的值。

  • watch 运行的时候不会立即执行,值改变后才会执行

  • watchEffect 运行后可立即执行。这一点可以通过 watch 的配置项 immediate 改变。

  • watchEffect有点像 computed ,多对一,不过不用写返回值

vue3与 vue2的比较

  • vue3使用 TS 重写

  • 支持 Composition API:基于函数的API,更加灵活组织组件逻辑(vue2用的是options api)。 可以用 scrtpt setup 来写。 这是 vue3 的语法糖,简化了组合式 API 的写法,并且运行性能更好。使用 script setup 语法糖的特点

  • 响应式系统提升:Vue3中响应式数据原理改成proxy,可监听动态新增删除属性,以及数组变化

  • 编译优化:vue2通过标记静态根节点优化diff,Vue3 标记和提升所有静态根节点,diff的时候只需要对比动态节点内容

  • 打包体积优化:treeshaking 不引入的包,不会打包进去; 移除了一些不常用的api(inline-template、filter)

  • 生命周期的变化:使用setup代替了之前的beforeCreate和created,其他只是改名字效果一样

  • Vue3 的 template 模板支持多个根标签

  • Vuex状态管理:创建实例的方式改变,Vue2为new Store , Vue3为createStore

  • Route 获取页面实例与路由信息:vue2通过this获取router实例,vue3通过使用 getCurrentInstance/ userRoute和userRouter方法获取当前组件实例

  • Props 的使用变化:vue2 通过 this 获取 props 里面的内容,vue3 直接通过 props

  • 父子组件传值:vue3 在向父组件传回数据时,如使用的自定义名称,如事件,需要在 emits 中定义一下

  • 父组件获取子组件的数据时,需要defineExpose 导出

  • Pinia 移除 mutations,只剩下 state 、 actions 、 getters 。