vue3面试知识点十大问

1.vue2中的响应式与vue3中有什么不同

vue2中响应式采用Object.defineProperty对对象中的属性进行getset拦截。创建observer类,为每个数据创建一个数组来管理依赖,在getter中收集依赖,在setter中通知依赖更新。所以每当属性进行读写操作时就会触发getset,从而实现对属性的监听。

vue2中对对象属性的访问需要先知道特定的key,所以对于对象中新增的属性、数组中通过下标新增数据会有些不足。

vue2中的全局的$set方法的本质就是给新增的属性手动observer

Object.defineProperty(car, 'price', {
  get() {},
  set() {}
})

vue3中的响应式则是借助Proxytarget是目标对象可以是数组甚至是另一个代理,handler通常是用来定制拦截行为,通常含有 hasgetsetdeleteProperty等方法。可以看到vue3对对象的代理不依赖对象属性,所以可以很好的解决vue2中的不足。

const proxy = new Proxy(target, {
  get: function(target, propKey, receiver) {
    return '10'
  }
})

2.vue3比vue2优化了哪些地方

  • 全局API的修改:vue2中是导出全局的vue对象,在单元测试中,很容易污染全局环境以及带来冲突。vue3中通过createApp 创建app实例,一切操作修改从直接操作Vue全局对象,转变成了操作vue实例
  • 一些全局的api支持了tree-shaking,变成了具名的导出,从vue对象中脱离。如nextTick的引用方式从Vue.nextTicke变成了import {nextTick, observable} from vue
  • 通过Composition API以逻辑来划分代码,更好的重用代码,vue2中对代码的抽离可以通过mixins,但是mixins存在命名冲突、暴露出来的变量来源不清晰等问题。composition api可以进行重命名,避免了命名冲突。
  • 对typescript更好的支持
  • 新增了一些其他的特性,比如teleportsuspense

3.vue3中的suspense组件

vue3中使用defineAsyncCompoent方法,方法接受返回promise的工厂函数,动态加载组件

const AsyncComp = defineAsyncComopent(
  () => new Promise((resolve, reject) => {
    resolve({
      template: '
test
' }) }) )

vue2中则是直接通过import导入。

4.vue3中的teleport组件

teleport像是一个传送门,允许我们控制在哪个dom节点下呈现html。to属性接受一个querySelector,设置父级节点。

实现原理:通过createBlock生成一个vnode,创建teleport组件,通过调用Teleport.process,选中父节点,mountChildren方法挂在到dom中。


5.说说虚拟dom及vue3中对虚拟dom对优化

虚拟dom就是一个js对象来描述dom节点,当数据发生变化时,对比变化前后的虚拟dom节点,通过dom-diff算法计算出需要更新的地方,然后来更新需要的视图。
vue中通过VNode类来实例化出不同类型的虚拟dom,比如注释节点通过isComment来表示是否是注释节点,text表示具体的注释信息。

export const createEmptyVNode = (text: string = '') => {
  const node = new VNode();
  node.text = text;
  node.isComment = true;
  return node;
}

优化前,在一个默认的Virtual Dom的diff中,需要遍历所有节点,去比较旧的props和新的props有没有变化

而优化之后,创建的vnode多了patch flag标记该节点的可变属性,当 diff 算法走到 _createBlock 函数的时候,会忽略所有的静态节点,只对有标记的动态节点进行对比,而且在多层的嵌套下依然有效。

6.vue3中的生命周期

vue3面试知识点十大问_第1张图片

beforeCreate和create几乎是同时在setup函数中进行触发的。生命周期函数的书写OnBeforeMount、OnMounted、onUpdated

vue3中多了两个调试钩子函数onRenderTracked onRenderTriggered,顾名思义就是在render重新绘制时进行触

7.vue中的key有什么作用

  • dom-diff中标识Vnode,标识变化前后是否是同一个组件
  • 通过key复用元素,所以修改某一个元素的key可以重新渲染该元素

8.vue3 的 watch 与 vue2 中有哪些不同

  • vue3 中的 watch 函数第一个参数为响应式对象、有 getter/settereffect 函数、或者这些类型数组;第二个参数为数据变化时的回调;第三个参数为 watchOption,提供是否立即监听和是否深度监听的配置。
  • vue3 可以多次使用 watch 方法

    
    watch(data, () => {})
    watch(() => data.name, () => {})
    watch([data, name], () => {})
  • vue3 的 setup 中不存在 this 对象,监听路由需要使用 vue-router 提供的 userRoute,vue2 则是在 watch 对象里添加'$route'进行监听

    import { useRoute } from "vue-router";
    // setup
    const route = useRoute();
    const userData = ref();
    
    // 当参数更改时获取用户信息
    watch(() => route.params, () => {});

9.vue3中watchEffect与watch的异同

不同点:

  • watchEffect立即执行传入的函数,在初始化时自动收集依赖,并在其依赖变更时重新运行该函数
  • watchEffect无法获取原值,只能得到变化后的值

相同点:两者都可通过StopHandle.stop()函数手动停止监听

const stopHandle = watchEffect();
handle.stop();

10.v-model的原理及vue3中v-model的改变

v-model通过在数据修改时,通知父级节点实现数据的双向绑定。其实是一个语法糖当满足以下两个条件时,可实现自定义组件的v-model:

  • 子组件受控接收prop
  • 数据修改时触发event把新的数据提交给父组件
props: {
  value: String
},
model: {
  prop: 'value',
  event: 'change'
}

vue3中升级了v-mode的用法,通过update:modelValue来触发事件,prop也被更改为modelValue。还在一个组件上支持多个v-model,如新增v-model:lastName等。

props: {
  modelValue: String,
}
emits: ['update:modelValue'],
methods: {
  changeTitle() {
    this.$emit('update:modelValue', title)
  }
}

参考链接

你可能感兴趣的:(前端vue.js面试)