前端Vue基础面试题

本文详细介绍了Vue的生命周期阶段、组件间的通信方式、v-if/v-show区别、computed/methods/watch的区别,以及Vuex与Redux的对比。同时涵盖了Vue3的效率提升和代码优化策略。
摘要由CSDN通过智能技术生成

Vue的生命周期 

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

  1. beforeCreate(创建前) :数据观测和初始化事件还未开始,此时 data 的响应式追踪、event/watcher 都还没有被设置,也就是说不能访问到data、computed、watch、methods上的方法和数据。

  2. created(创建后) :实例创建完成,实例上配置的 options 包括 data、computed、watch、methods 等都配置完成,但是此时渲染得节点还未挂载到 DOM,所以不能访问到 $el 属性。

  3. beforeMount(挂载前) :在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。此时还没有挂载html到页面上。

  4. mounted(挂载后) :在el被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html 页面中。此过程中进行ajax交互。

  5. beforeUpdate(更新前) :响应式数据更新时调用,此时虽然响应式数据更新了,但是对应的真实 DOM 还没有被渲染。

  6. updated(更新后) :在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。此时 DOM 已经根据响应式数据的变化更新了。调用时,组件 DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。

  7. beforeDestroy(销毁前) :实例销毁之前调用。这一步,实例仍然完全可用,this 仍能获取到实例。

  8. destroyed(销毁后) :实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务端渲染期间不被调用。

另外还有 keep-alive 独有的生命周期,分别为 activateddeactivated 。用 keep-alive 包裹的组件在切换时不会进行销毁,而是缓存到内存中并执行 deactivated 钩子函数,命中缓存渲染后会执行 activated 钩子函数。

Vue的组件之间的通信方式有哪些 

父子组件通信

  1. prop

  2. event

  3. style和class

  4. attribute

  5. natvie修饰符

  6. $listeners

  7. sync修饰符

  8. ref

跨组件通信

  1. Provide和Inject

  2. router

  3. vuex

  4. store模式

  5. eventbus

详情看官网文档 v2.cn.vuejs.org/v2/api

v-if和v-show的区别 

  • v-if是动态的添加或者删除DOM元素,v-show是通过设置DOM元素的display样式属性控制

  • v-if有更高的切换消耗,v-show有更高的初始渲染消耗;

computed和methods有什么区别

  • 在使用时,computed当做属性使用,而methods则当做方法调用

  • computed可以具有getter和setter,因此可以赋值,而methods不行

  • computed无法接收多个参数,而methods可以

  • computed具有缓存,而methods没有

watch与computed的区别是什么

  • computed 计算属性 : 依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。

  • watch 侦听器 : 更多的是观察的作用,无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。

运用场景:

  • 当需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时都要重新计算。

  • 当需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许执行异步操作 ( 访问一个 API ),限制执行该操作的频率,并在得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

Vue组件的data为什么必须是函数 

组件中的 data 写成一个函数,数据以函数返回值形式定义。这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份 data,就会造成一个变了全都会变的结果。

nextTick的作用是什么?他的实现原理是什么? 

作用vue 更新 DOM 是异步更新的,数据变化,DOM 的更新不会马上完成,nextTick 的回调是在下次 DOM 更新循环结束之后执行的延迟回调。

实现原理

  • nextTick 主要使用了宏任务和微任务。根据执行环境分别尝试采用

  • Promise:可以将函数延迟到当前函数调用栈最末端

  • MutationObserver :是 H5 新加的一个功能,其功能是监听 DOM 节点的变动,在所有 DOM 变动完成后,执行回调函数

  • setImmediate:用于中断长时间运行的操作,并在浏览器完成其他操作(如事件和显示更新)后立即运行回调函数

  • 如果以上都不行则采用 setTimeout 把函数延迟到 DOM 更新之后再使用

原因是宏任务消耗大于微任务,优先使用微任务,最后使用消耗最大的宏任务。

Vue2.x双向数据绑定原理 

Vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

Proxy 相比 defineProperty 的优势在哪里 

原因在于 Object.defineProperty 本身存在的一些问题:

  • Object.defineProperty 只能劫持对象属性的 gettersetter 方法。

  • Object.definedProperty不支持数组(可以监听数组,不过数组方法无法监听自己重写),更准确的说是不支持数组的各种 API(所以 Vue 重写了数组方法)

而相比 Object.definePropertyProxy 的优点在于:

  • Proxy 是直接代理劫持整个对象。

  • Proxy 可以直接监听对象和数组的变化,并且有多达 13 种拦截方法。

目前,Object.definedProperty 唯一比 Proxy 好的一点就是兼容性,不过 Proxy 新标准也受到浏览器厂商重点持续的性能优化当中。

Vue中的Key 的作用是什么 

key 的作用主要是为了高效的更新虚拟 DOM。另外 vue 中在使用相同标签名元素的过渡切换时,也会使用到 key 属性,其目的也是为了让 vue 可以区分它们,否则 vue只会替换其内部属性而不会触发过渡效果。

Vue2.x的diff算法的理解 

Diff算法实现的是最小量更新虚拟DOM。 这句话虽然简短,但是涉及到了两个核心要素:

  • 虚拟DOM、最小量更新。 虚拟DOM指的就是将真实的DOM树构造为js对象的形式,从而解决浏览器操作真实DOM的性能问题。 Diff的用途就是在新老虚拟DOM之间找到最小更新的部分,从而将该部分对应的DOM进行更新。

Vuex中action和mutation的区别

  • Mutation专注于修改State,理论上是修改State的唯一途径;Action业务代码、异步请求。

  • Mutation:必须同步执行;Action:可以异步,但不能直接操作State。

  • 在视图更新时,先触发actions,actions再触发mutation

Vue3.x的效率提升主要是哪个方面 

静态提升

预字符串化

当编译器遇到大量连续的静态内容,会直接将其编译为一个普通字符串节点

缓存事件处理函数

Block Tree

vue2在对比新旧树的时候,并不知道哪些节点是静态的,哪些是动态的,因此只能一层一层比较,这就浪费了大部分时间在比对静态节点上

vue3只对比动态的节点

PatchFlag

vue2在对比每一个节点时,并不知道这个节点哪些相关信息会发生变化,因此只能将所有信息依次比对

vue3仅对比元素内容

相比vue3.x对比vue2.x变化 

  • 源码组织方式变化:使用 TS 重写

  • 支持 Composition API:基于函数的API,更加灵活组织组件逻辑(vue2用的是options api

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

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

  • 打包体积优化:移除了一些不常用的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 在向父组件传回数据时,如使用的自定义名称,如 backData,则需要在 emits 中定义一下

Vue代码优化方面 

执行代码优化

  1. 使用key
    • 对于通过循环生成的列表,应给每个列表项一个稳定且唯一的key,这有利于在列表变动时,尽量少的删除、新增、改动元素

  2. 使用冻结对象
    • 冻结对象不会被响应式

  3. 使用计算属性

  4. 保持对象引用稳定

  5. 合理的使用v-if和v-show

  6. 使用延迟装载(requestAnimationFrame)

  7. keep-alive

  8. 长列表优化

Vuex的原理 

核心流程中的主要功能:

  • Vue Components 是 vue 组件,组件会触发(dispatch)一些事件或动作,也就是图中的 Actions;

  • 在组件中发出的动作,肯定是想获取或者改变数据的,但是在 vuex 中,数据是集中管理的,不能直接去更改数据,所以会把这个动作提交(Commit)到 Mutations 中;

  • 然后 Mutations 就去改变(Mutate)State 中的数据;

  • 当 State 中的数据被改变之后,就会重新渲染(Render)到 Vue Components 中去,组件展示更新后的数据,完成一个流程。

Vue与React对比? 

相同点

  • 都有组件化思想

  • 都支持服务器端渲染

  • 都有Virtual DOM(虚拟dom)

  • 数据驱动视图

  • 都有支持native的方案:VueweexReactReact native

  • 都有自己的构建工具:Vuevue-cliReactCreate React App

区别

  • 数据流向的不同。react从诞生开始就推崇单向数据流,而Vue是双向数据流

  • 数据变化的实现原理不同。react使用的是不可变数据,而Vue使用的是可变的数据

  • 组件化通信的不同。react中我们通过使用回调函数来进行通信的,而Vue中子组件向父组件传递消息有两种方式:事件和回调函数

  • diff算法不同。react主要使用diff队列保存需要更新哪些DOM,得到patch树,再统一操作批量更新DOM。Vue 使用双向指针,边对比,边更新DOM

vuex和redux之间的区别 

从实现原理上来说,最大的区别是两点:

Redux使用的是不可变数据,而Vuex的数据是可变的。Redux每次都是用新的state替换旧的state,而Vuex是直接修改

Redux在检测数据变化的时候,是通过diff的方式比较差异的,而Vuex其实和Vue的原理一样,是通过 getter/setter来比较的(如果看Vuex源码会知道,其实他内部直接创建一个Vue实例用来跟踪数据变化)

最后:

如果你现在正在找工作,可以私信“web”或者直接添加小助理进群领取前端面试小册、简历优化修改、大厂内推以及更多阿里、字节大厂面试真题合集,和p8大佬一起交流。

  • 28
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Web面试那些事儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值