看了涡流大佬的面试文章的总结(vue)

392 阅读5分钟

本人目前大三,4月末进行了人生第一场面试。不尽人意。总觉得自己什么都了解,但是又觉得什么都不会。前几天看见涡流老哥的面试文章总结。来进行一些总结吧。

涡流老哥原博文。前端两年经验,历时一个月的面经和总结

有些的不对的地方,请指正,一起总结。

computed和watch的区别

computed是计算属性。用来计算一个相对复杂的表达式,然后返回,并且内部会缓存该值。如果收集的依赖项未变化,那么他就直接返回上次计算的值,将不重新计算。内部是用过_dirty来控制是否使用缓存的。

源码位置:packages/reactivity/computed.ts image.png

深度解析:Vue3如何巧妙的实现强大的computed

watch主要是监听依赖的变化,然后做一些逻辑处理。注意watch监听,对于reactive对象来说,他返回的新旧值都是一样的,因为都是同一个引用。但是对于监听普通的值和对象(只对第一层属性来说,改变其他层的属性,依旧是新旧值都一样的。),那么他会返回的新旧值就不一样了。

具体可以访问这里

我个人感觉,开发中监听一个一个普通值的是最常见的。

data为什么是个函数,而不是对象

因为它需要为每一个实例创建唯一的data引用,每次创建组件实例,如果data是函数的话,每次返回的对象都是不同的,防止数据紊乱。

为了防止多个组件对象之间共用一个data,产生数据污染。

watch能监听computed的属性吗

可以监听,因为computed也是返回一个ref对象

    Vue.createApp({
      template: `
      <div>
        <p>{{computedVal}}</p>
        <button @click="handleClick">改变computed</button>
      </div>
      `,
      setup (props) {
        const refVal=Vue.ref("pp")

        let computedVal=Vue.computed({
          get () {
            return refVal.value
          },
          set (newVal) {
            refVal.value=newVal
          }
        })

        const handleClick=() => {
          console.log("=====")
          computedVal.value="oo"
        }

        Vue.watch(computedVal,(v1,v2) => {
          console.log("v1",v1) // oo
          console.log("v2",v2) // pp
        })

        return {
          computedVal,
          handleClick
        }
      }
    }).mount("#app")

vue的响应式原理

重学vue(2, 3)及其生态+TypeScript 之 vue部分实现和源码分析

vue的生命周期

  • beforeCreate: 在实例初始化之后、进行数据侦听和事件/侦听器的配置之前同步调用。
  • created:在实例创建完成后被立即同步调用。在这一步中,实例已完成对选项的处理,意味着以下内容已被配置完毕:数据侦听、计算属性、方法、事件/侦听器的回调函数。然而,挂载阶段还没开始,且 $el property 目前尚不可用。
  • setup 取代 beforeCreate, created
  • beforeMount: 在挂载开始之前被调用:相关的 render 函数首次被调用。
  • mounted:在实例挂载完成后被调用,这时候传递给 app.mount的元素已经被新创建的 vm.$el 替换了。如果根实例被挂载到了一个文档内的元素上,当 mounted 被调用时, vm.$el 也会在文档内。 注意 mounted 不会保证所有的子组件也都被挂载完成。如果你希望等待整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick
  • beforeUpdate:在数据发生改变后,DOM 被更新之前被调用。这里适合在现有 DOM 将要被更新之前访问它,比如移除手动添加的事件监听器。
  • updated:在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用。注意,updated 不会保证所有的子组件也都被重新渲染完毕。如果你希望等待整个视图都渲染完毕,可以在 updated 内部使用 vm.$nextTick
  • beforeUnmount:在卸载组件实例之前调用。在这个阶段,实例仍然是完全正常的。
  • unmounted:卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。 image.png 被keep-alieve缓存组件的生命周期:
  • activated:被 keep-alive 缓存的组件激活时调用。
  • deactivated:被 keep-alive 缓存的组件失活时调用。 生命周期钩子

生命周期钩子composition api

mounted拿到数据后可以直接获取dom吗

mounted只是在组件实例挂载的时候执行,数据改变不会再次执行。所以只会执行一次。

nextTick原理

将回调推迟到下一个 DOM 更新周期之后执行。在更改了一些数据以等待 DOM 更新后立即使用它。他会等到组件的所有子组件也加载完毕后执行的。

使用场景:想要操作基于最新数据的生成DOM时,就将这个操作放在 nextTick 的回调中。例如计算图片加载后的高度,然后计算图片下方元素的位置。

将传入的回调函数包装成异步任务,异步任务又分微任务和宏任务,为了尽快执行所以优先选择微任务。

源码位置:core\packages\runtime-core\src\scheduler.ts image.png

vue模板(template)里为什么不能使用多个头结点?

这个是值多个根节点吗?

因为非props的attrs挂载会出现错误。

vuex为什么同时设计mutation和action?只设计一个行不行?

  • mutation: 处理同步数据改变

在mutation里面加入了异步处理的函数。其实mutation是可以正常使用的,但是我们在日常的开发中debug的时候,我们需要查看devtool中的mutation日志。

理论上来说,是mutation走一步,devtool记录一步,但是在mutation中加入异步函数就会导致我们devtool的记录失败,因为devtool不知道你里面的异步函数什么时候调用,在哪里调用。

  • action:处理异步数据的变化。

不行,因为 vue dev-tools不能追踪到异步数据的变化。

vue2和 vue3 在数据绑定这一块有什么区别?

  • vue2通过Object.defineProperty

  • vue3通过Proxy

重学vue(2, 3)及其生态+TypeScript 之 vue部分实现和源码分析

vue挂载和卸载父子组件生命周期钩子执行顺序

image.png

image.png

vue的优化方案(等同于如何编写可读性高、易维护且高性能的vue代码)

Vue 项目性能优化 — 实践指南(网上最全 / 详细)

keep-alive的原理,使用有什么问题?如何解决?

【源码分析】vue3 KeepAlive 原理