小工具知识网

当前位置: 首页 > 行业知识 > 2024高频前端面试题 Vue2 和 Vue3 篇

行业知识

2024高频前端面试题 Vue2 和 Vue3 篇

2026-11-06 09:16:52 来源:互联网转载

* Vue2 和 Vue3的区别:

1)双向数据绑定原理的区别

2)根节点的不同

Vue2只能一个���节点

Vue3在组件中可以放置多个根节点

3)Vue3中采用composition API 

vue2:采用的选项型API(opsition API)

vue3:采用的组合型API(composition API)

4)建立的数据方式不同 

vue2:数据是放置在data属性中

vue3:需要使用setup 方法,该方法在初始化构造的时候触发

注:ref:需要value 访问,内部还是使用的defineProperty set get 方法进行监听(proxy 不支持基本类型的监听)

reactive: 使用的proxy对数据进行的一个代理

5)生命周期函数不同 

6)diff算法不同

7)父子传参不同

vue2:父传子,用props,子传父用事件 Emitting Events。在vue2中,会调用this$emit然后传入事件名和对象。

vue3:父传子,用props,子传父用事件 Emitting Events。在vue3中的setup()中的第二个参数content对象中就有emit,那么我们只要在setup()接收第二个参数中使用分解对象法取出emit就可以在setup方法中随意使用了。

1. 什么是MVVM?

M - Model 数据:负责数据管理和业务逻辑。
V - View 视图:负责用户界面的展示和呈现。
VM - ViewModel 视图-数据:它是View和Model的粘合体,负责View和Model的交互和协作

vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变; 

核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法,get set 方法。

在MVVM的框架下视图和模型是不能直接通信的。它们通过ViewModel来通信,ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。并且MVVM中的View 和 ViewModel可以互相通信。

MVVM 是一种软件架构模式。它是基于 MVC 的一种演变,将视图和数据绑定的方式更加紧密地结合在一起。 

2. 什么是MVC? 

M - Model 数据:负责数据管理和业务逻辑。模型表示应用程序中的数据结构以及对数据的操作。
V - View 视图:负责用户界面的展示和呈现,通常是用户可以看到和与之交互的部分。
C - Controller 控制器: 负责接收用户的输入并作出响应,它处理用户与模型和视图之间的交互。控制器将用户的操作转发给模型进行处理,并将模型的结果传递给视图进行展示。

MVC 的优势:

能够将应用程序的各个功能模块分离开来,提高代码的可维护性和可扩展性。通过明确定义了各个组件的职责,开发人员可以更好地组织和管理代码,同时也使得代码更容易被复用。

3. MVVM 和 MVC的区别 

1、mvvm各部分的通信是双向的,而mvc各部分通信是单向的;

2、mvvm是真正将页面与数据逻辑分离放到js里去实现,而mvc里面未分离。

MVC允许在不改变视图的情况下改变视图对用户输入的响应方式,用户对View的操作交给了Controller处理,在Controller中响应View的事件调用Model的接口对数据进行操作,一旦Model发生变化便通知相关视图进行更新。 

4. Vue2响应式原理 

对象类型:

使用 Object.defineProperty 遍历对象的每一个属性,把每一个属性变成一个 getter 和 setter 函数,读取属性的时候调用 getter,给属性赋值的时候就会调用 setter,这就是数据劫持。

数组类型:

通过重写更新数组的一系列方法,保留原功能的基础上增加一些数据劫持的代码(也就是将数据变为可监控的)来实现拦截。

7个方法:push、pop、shift、unshift、splice、sort、reverse。

存在问题:

1.新增属性、删除属性, 界面不会更新。

2.直接通过下标修改数组, 界面不会自动更新。

解决方法:

vue2中 $set 可以解决这些问题。

5.  Vue3响应式原理 

通过(Proxy)代理实现: 拦截对象中任意属性的变化, 包括属性值的读写, 属性的添加, 属性的删除等操作。

通过(Reflect)(反射); 被代理的对象, 属性进行操作。

vue3.0 中不存在vue2.0 中说的这些问题

在一个对象中新增, 删除, 修改属性, 界面不会自动更新。

直接通过下标修改数组, 界面不会自动更新。

6. Proxy 与 Object.defineProperty 优劣对比 

1)Proxy的优势如下:

  1. Proxy可以直接监听对象⽽⾮属性 。
  2. Proxy可以直接监听数组的变化 。
  3. Proxy有多达13种拦截⽅法,不限于apply、ownKeys、deleteProperty、has等等是 Object.defineProperty 不具备的 。
  4. Proxy返回的是⼀个新对象,我们可以只操作新的对象达到⽬的,⽽ Object.defineProperty 只能遍历对象属性直接修改。
  5. Proxy作为新标准将受到浏览器⼚商重点持续的性能优化,也就是传说中的新标准的性能红利 。

2)Object.defineProperty的优势如下:

  1. 兼容性好,⽀持IE9。

7. Vue2和Vue3的diff的区别 

Vue2:

diff算法就是进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方,最后用patch记录的消息去局部更新Dom。

diff算法会比较每一个vnode,而对于一些不参与更新的元素,进行比较是有点消耗性能的。

Vue3:

diff算法在初始化的时候会给每个虚拟节点添加一个patchFlags,patchFlags就是优化的标识。

只会比较patchFlags发生变化的vnode,进行更新视图,对于没有变化的元素做静态标记,在渲染的时候直接复用。

详细内容比较多,但这个是重点部分。请跳转至:

Vue2 和 Vue3 的 Diff 算法的区别-CSDN博客

Vue diff算法_vue2 diff算法和vue3diff算法-CSDN博客

8. 生命周期的理解

Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。

9. Vue2的生命周期

创建阶段:

beforeCreate:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
created:在实例创建完成后被调用,此阶段完成了数据观测 (data observer)、属性和方法的运算,以及 watch/event 事件的设置。但是此时还没有挂载到 DOM 上。

挂载阶段:

beforeMount:在挂载开始之前被调用,相关的 render 函数首次被调用。

mounted:在实例被挂载到 DOM 后调用,此阶段完成了模板编译并且将实例挂载到 DOM 上。

更新阶段:

beforeUpdate:在数据更新之前被调用,发生在虚拟 DOM 重新渲染和打补丁之前。

updated:在数据更新完成后被调用,实例的 DOM 已经更新。

销毁阶段:

beforeDestroy:在实例销毁之前调用,此时实例仍然完全可用。

destroyed:在实例销毁后调用,此阶段完成了实例的事件监听器和子组件的销毁。

两个特殊的生命周期钩子函数: 

activated:在使用 keep-alive 组件时,被激活的组件会调用该函数。

deactivated:在使用 keep-alive 组件时,被停用的组件会调用该函数。

10. Vue3的生命周期         

1)普通写法:      2)setup中写生命周期:
beforeCreatesetup()
createdsetup()
beforeMount onBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted

11. Vue2和Vue3生命周期区别

12. 在哪个生命周期内调用异步请求?

可以在钩子函数 created、beforeMount、mounted 中进行调用,因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。

但是本人推荐在 created 钩子函数中调用异步请求,因为在 created 钩子函数中调用异步请求有以下优点:

  • 能更快获取到服务端数据,减少页面 loading 时间;
  • ssr 不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性;

    13. 父组件可以监听到子组件的生命周期吗? 

    比如有父组件 Parent 和子组件 Child,如果父组件监听到子组件挂载 mounted 就做一些逻辑处理,可以通过以下写法实现:

    // Parent.vue    // Child.vuemounted() {  this.$emit("mounted");}
    //  Parent.vuedoSomething() {   console.log('父组件监听到 mounted 钩子函数 ...');},    //  Child.vuemounted(){   console.log('子组件触发 mounted 钩子函数 ...');},        // 以上输出顺序为:// 子组件触发 mounted 钩子函数 ...// 父组件监听到 mounted 钩子函数 ... 

    当然 @hook 方法不仅仅是可以监听 mounted,其它的生命周期事件,例如:created,updated 等都可以监听。

    14. 组件中 data 为什么是一个函数? 

    因为 Vue 在创建组件实例时,会为每个组件实例都创建一个独立的数据作用域。

    如果将 data 直接定义为一个对象,那么所有组件实例都将共享同一个数据对象,这样就无法实现数据的隔离。

    data 是函数的话那么每次创建组件实例时,都会调用这个函数并返回一个新的对象。

    未完待续...

上一篇:服务器怎么开启所有核心?

下一篇:宝塔面板操作指南,零基础教程,轻松掌握操作技巧!