Vue3.0面试题汇总

news2024/9/29 18:54:28

Composition API 可以说是Vue3的最大特点,那么为什么要推出Composition Api,解决了什么问题?

通常使用Vue2开发的项目,普遍会存在以下问题:

  • 代码的可读性随着组件变大而变差
  • 每一种代码复用的方式,都存在缺点
  • TypeScript支持有限

以上通过使用Composition Api都能迎刃而解


以下面试题汇总自2022(金三银四)-vue3面试题汇总文章

一、Options Api与Composition Api的区别?

1、Options Api:选项API,即以vue为后缀的文件,通过定义methodscomputedwatchdata等属性与方法,共同处理页面逻辑。
用组件的选项 (data、computed、methods、watch) 组织逻辑在大多数情况下都有效。然而,当组件变得复杂,导致对应属性的列表也会增长,这可能会导致组件难以阅读和理解。

2、Composition API 中,组件根据逻辑功能来组织的,一个功能所定义的所有 API 会放在一起( 更加的 高内聚,低耦合 )。

3、Composition Api 相对Options Api的两大优点:

  • 逻辑组织
    • Options Api在处理一个大型的组件时,内部的逻辑点容易碎片化,可能同时存在于method,computed,watch等API中,我们必须不断地“跳转”相关代码的选项块,这种碎片化使得理解和维护复杂组件变得困难。
    • Composition Api将某个逻辑关注点相关的代码全都放在一个函数里,这样,当需要修改一个功能时,就不再需要在文件中跳来跳去。
  • 逻辑复用
    • vue2.0中,当混入多个mixin会存在两个非常明显的问题:命名冲突、数据来源不清晰
    • Composition Api可以通过编写多个hooks函数就很好的解决了

总结

  • 在逻辑组织和逻辑复用方面,Composition API是优于Options API
  • 因为Composition API几乎是函数,会有更好的类型推断
  • Composition APItree-shaking 友好,代码也更容易压缩
  • Composition API中见不到this的使用,减少了this指向不明的情况
  • 如果是小型组件,可以继续使用Options API,也是十分友好的

二、Vue3.0性能提升主要是通过哪几方面体现的?

1、编译阶段优化

回顾Vue2,我们知道每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把用到的数据property记录为依赖,当依赖发生改变,触发setter,则会通知watcher,从而使关联的组件重新渲染。

因此,Vue3在编译阶段,做了进一步优化:

diff算法优化

vue3diff算法中相比vue2增加了静态标记,其作用是为了会发生变化的地方添加一个flag标记,下次发生变化的时候直接找该地方进行比较。

静态提升

Vue3中对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用。免去了重复的创建操作,优化内存。

没做静态提升之前,未参与更新的元素也在render函数内部,会重复创建阶段
做了静态提升后,未参与更新的元素,被放置在render 函数外,每次渲染的时候只要取出即可。同时该元素会被打上静态标记值为-1,特殊标志是负整数表示永远不会用于 Diff

事件监听缓存

默认情况下绑定事件行为会被视为动态绑定(没开启事件监听器缓存),所以每次都会去追踪它的变化。开启事件侦听器缓存后,没有了静态标记。也就是说下次diff算法的时候直接使用

SSR优化

当静态内容大到一定量级时候,会用createStaticVNode方法在客户端去生成一个static node,这些静态node,会被直接innerHtml,就不需要创建对象,然后根据对象渲染。

2、源码体积

相比Vue2Vue3整体体积变小了,除了移出一些不常用的API,最重要的是Tree shanking

任何一个函数,如ref、reavtived、computed等,仅仅在用到的时候才打包没用到的模块都被摇掉,打包的整体体积变小

3、响应式系统

vue2中采用 defineProperty来劫持整个对象,然后进行深度遍历所有属性,给每个属性添加getter和setter,实现响应式。

vue3采用proxy重写了响应式系统,因为proxy可以对整个对象进行监听,所以不需要深度遍历。

  • 可以监听动态属性的添加
  • 可以监听到数组的索引和数组length属性
  • 可以监听删除属性

三、Vue3.0里为什么要用 Proxy API 替代 defineProperty API ?

1、vue2中采用 defineProperty来劫持整个对象,然后进行深度遍历所有属性,给每个属性添加getter和setter,实现响应式。但是存在以下的问题:

  • 检测不到对象属性的添加和删除
  • 数组API方法无法监听到
  • 需要对每个属性进行遍历监听,如果嵌套对象,需要深层监听,造成性能问题

2、proxy:监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作。

总结:

  • Object.defineProperty只能遍历对象属性进行劫持
  • Proxy直接可以劫持整个对象,并返回一个新对象,我们可以只操作新的对象达到响应式目的
  • Proxy可以直接监听数组的变化(push、shift、splice)
  • Proxy有多达13种拦截方法,不限于apply、ownKeys、deleteProperty、has等等,这是Object.defineProperty不具备的

四、Vue3.0响应式原理

vue3 响应式是使用 ES6 的 proxy 和 Reflect 相互配合实现数据响应式,解决了 vue2 中视图不能自动更新的问题。

proxy 是深度监听,所以可以监听对象和数组内的任意元素,从而可以实现视图实时更新。

详细的原理可查看vue3.0 响应式原理(超详细)

总结响应式大致分为三个阶段:

  • 初始化阶段:初始化阶段通过组件初始化方法形成对应的proxy对象,然后形成一个负责渲染的effect
  • get依赖收集阶段:通过解析template,替换真实data属性,来触发get,然后通过stack方法,通过proxy对象key形成对应的deps,将负责渲染的effect存入deps。(这个过程还有其他的effect,比如watchEffect存入deps中 )。
  • set派发更新阶段:当我们 this[key] = value 改变属性的时候,首先通过trigger方法,通过proxy对象key找到对应的deps,然后给deps分类分成computedRunnerseffect,然后依次执行,如果需要调度的,直接放入调度。

Proxy只会代理对象的第⼀层,那么Vue3⼜是怎样处理这个问题的呢?

判断当前Reflect.get的返回值是否为Object,如果是则再通过 reactive ⽅法做代理, 这样就实现了深度观测。

监测数组的时候可能触发多次get/set,那么如何防⽌触发多次呢?

我们可以判断key是否为当前被代理对象target⾃身属性,也可以判断旧值与新值是否相等,只有满⾜以上两个条件之⼀时,才有可能执⾏trigger。


五、说说Vue 3.0中Treeshaking特性?举例说明一下?

1、是什么?

  • Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination
  • 简单来讲,就是在保持代码运行结果不变的前提下,去除无用的代码

Vue2中,无论我们使用什么功能,它们最终都会出现在生产代码中。主要原因是Vue实例在项目中是单例的,捆绑程序无法检测到该对象的哪些属性在代码中被使用到。

Vue3源码引入tree shaking特性,将全局 API 进行分块。如果您不使用其某些功能,它们将不会包含在您的基础包中

2、如何做?

Tree shaking是基于ES6模板语法(importexports),主要是借助ES6模块的静态编译思想,在编译时就能确定模块的依赖关系,以及输入输出的变量。

Tree shaking无非就是做了两件事:

  • 编译阶段利用ES6 Module判断哪些模块已经加载
  • 判断那些模块和变量未被使用或者引用,进而删除对应代码

3、作用(好处)?

通过Tree shakingVue3给我们带来的好处是:

  • 减少程序体积(更小)
  • 减少程序执行时间(更快)
  • 便于将来对程序架构进行优化(更友好)

以下面试题汇总自「2022」打算跳槽涨薪,必问面试题及答案——VUE3 篇

六、Vue3 新特性有哪些?

1、性能提升

  • 响应式性能提升,由原来的 Object.defineProperty 改为基于ES6Proxy ,使其速度更快
  • 重写了 Vdom (diff算法优化,增加静态标志)
  • 进行模板编译优化(静态提升,不参与更新的元素只被创建一次)
  • 更加高效的组件初始化

2、更好的支持 typeScript

  • Vue.js 2.x 选用 Flow 做类型检查,来避免一些因类型问题导致的错误,但是 Flow 对于一些复杂场景类型的检查,支持得并不好。
  • Vue.js 3.0 抛弃了 Flow ,使用 TypeScript 重构了整个项目
  • TypeScript 提供了更好的类型检查,能支持复杂的类型推断

3、新增 Composition API

Composition APIvue3 新增的功能,比 mixin 更强大。它可以把各个功能模块独立开来,提高代码逻辑的可复用性,同时代码压缩性更强。

Vue3 中,定义 methodswatchcomputeddata数据等都放在了 setup() 函数中。

setup()函数会在created()生命周期之前执行。执行顺序为:beforeCreate > setup > created

4、新增组件

  • Fragment 不再限制 template 只有一个根节点。
  • Teleport 传送门,允许我们将控制的内容传送到任意的 DOM 中。
  • Suspense 等待异步组件时渲染一些额外的内容,让应用有更好的用户体验。

5、Tree-shaking:支持摇树优化

摇树优化后会将不需要的模块修剪掉,真正需要的模块打到包内。优化后的项目体积只有原来的一半,加载速度更快。

6、Custom Renderer API: 自定义渲染器

实现 DOM 的方式进行 WebGL 编程。


七、vue3 组合式API生命周期钩子函数有变化吗?

setup 是围绕 beforeCreatecreated 生命周期钩子运行的,所以不需要显示的定义它们。其他的钩子都可以编写到 setup 内。

值得注意的是组合式API中的钩子函数,通过在生命周期钩子前面加上 on 来访问组件的生命周期钩子。需要注册,并且只能在 setup 期间同步使用,因为它们依赖于内部的全局状态来定位当前组件实例。

下图是选项式API 和 组合式API 生命周期钩子对比:

image.png


八、watch 和 watchEffect 的区别?

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

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

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

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

  • watch 运行的时候不会立即执行,值改变后才会执行,而 watchEffect 运行后可立即执行。这一点可以通过 watch 的配置项 immediate 改变。

  • watchEffect有点像 computed

    • computed 注重的计算出来的值(回调函数的返回值), 所以必须要写返回值。
    • watcheffect注重的是过程(回调函数的函数体),所以不用写返回值。

    image.png

  • watchvue2.xwatch 配置功能一致,但也有两个小坑

    • 监视 reactive 定义的响应式数据时,oldValue 无法正确获取,强制开启了深度监视(deep配置失效)
    • 监视 reactive 定义的响应式数据中某个属性时,deep配置有效
let sum = ref(0)
let msg = ref('你好啊')
let person = reactive({
	name:'张三',
	age:18,
	job:{
		j1:{
			salary:20
		}
	}
})

//情况1:监视ref定义的响应式数据
watch(sum,(newValue, oldValue)=>{
	console.log("sum变化了", newValue, oldValue),(immediate:true)
})
//情况2:监视多个ref定义的响应式数据
watch([sum, msg],(newValue, oldValue)=>{
	console.log("sum或msg变化了", newValue, oldValue),(immediate:true)
})
//情况3:监视reactive定义的响应式数据
//若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue,且强制开启了深度监视。
watch(person,(newValue, oldValue)=>{
	console.log("person变化了", newValue, oldValue),(immediate:true,deep:false) //此处的deep配置不再生效。
})
//情况4:监视reactive所定义的一个响应式数据中的某个属性
watch(()=>person.name,(newValue, oldValue)=>{
	console.log("person.name变化了", newValue, oldValue)
})
//情况5:监视reactive所定义的一个响应式数据中的某些属性
watch([()=>person.name, ()=>person.age],(newValue, oldValue)=>{
	console.log("person.name或person.age变化了", newValue, oldValue)
})
//特殊情况:
watch(()=>person.job,(newValue, oldValue)=>{
	console.log("person.job变化了", newValue, oldValue)
}, {deep:true})


九、v-if 和 v-for 的优先级哪个高?

vue2v-for 的优先级更高,但是在 vue3 中优先级改变了。v-if 的优先级更高。


十、script setup 是干啥的?

scrtpt setupvue3 的语法糖,简化了组合式 API 的写法,并且运行性能更好。使用 script setup 语法糖的特点:

  • 属性和方法无需返回,可以直接使用。
  • 引入组件的时候,会自动注册,无需通过 components 手动注册。
  • 使用 defineProps 接收父组件传递的值。
  • useAttrs 获取属性,useSlots 获取插槽,defineEmits 获取自定义事件。
  • 默认不会对外暴露任何属性,如果有需要可使用 defineExpose

十一、Vue2/Vue3组件通信方式?

Vue3的8种和Vue2的12种组件通信,值得收藏

Vue3通信方式:

  • props
  • $emit
  • expose / ref
  • $attrs
  • v-model
  • provide / inject(原理:原型链)
  • Vuex/pinia
  • mitt

Vue2.x 组件通信共有12种

  • props
  • $emit / v-on
  • .sync
  • v-model
  • ref
  • children/children / children/parent
  • attrs/attrs / attrs/listeners
  • provide / inject
  • EventBus
  • Vuex
  • $root
  • slot

十二、ref与reactive的区别?

ref与reactive 是 Vue3 新推出的主要 API 之一,它们主要用于响应式数据的创建。

  • template 模板中使用的数据和方法,都需要通过 setup 函数 return 出去才可以被使用。
  • ref 函数创建的响应式数据,在模板中可以直接被使用,在 JS 中需要通过 .value 的形式才能使用。
  • ref 函数可以接收原始数据类型引用数据类型
  • reactive 函数只能接收引用数据类型
  • ref 底层还是使用 reactive 来做,ref 是在 reactive 上在进行了封装,增强了其能力,使它支持了对原始数据类型的处理。
  • 在 Vue3 中 reactive 能做的,ref 也能做,reactive 不能做的,ref 也能做。

十三、EventBus与mitt区别?

Vue3.0通关秘籍

Vue2 中我们使用 EventBus 来实现跨组件之间的一些通信,它依赖于 Vue 自带的 $on/$emit/$off 等方法,这种方式使用非常简单方便,但如果使用不当也会带来难以维护的毁灭灾难。

Vue3 中移除了这些相关方法,这意味着 EventBus 这种方式我们使用不了, Vue3 推荐尽可能使用 props/emitsprovide/injectvuex 等其他方式来替代。

当然,如果 Vue3 内部的方式无法满足你,官方建议使用一些外部的辅助库,例如:mitt。

优点

  • 非常小,压缩后仅有 200 bytes
  • 完整 TS 支持,源码由 TS 编码。
  • 跨框架,它并不是只能用在 Vue 中,ReactJQ 等框架中也可以使用。
  • 使用简单,仅有 onemitoff 等少量实用API。

十四、谈谈pinia?

Vue3.0通关秘籍

Pinia 是 Vue 官方团队成员专门开发的一个全新状态管理库,并且 Vue 的官方状态管理库已经更改为了 Pinia。在 Vuex 官方仓库中也介绍说可以把 Pinia 当成是不同名称的 Vuex 5,这也意味不会再出 5 版本了。

优点

  • 更加轻量级,压缩后提交只有1.6kb
  • 完整的 TS 的支持,Pinia 源码完全由 TS 编码完成。
  • 移除 mutations,只剩下 stateactionsgetters
  • 没有了像 Vuex 那样的模块镶嵌结构,它只有 store 概念,并支持多个 store,且都是互相独立隔离的。当然,你也可以手动从一个模块中导入另一个模块,来实现模块的镶嵌结构。
  • 无需手动添加每个 store,它的模块默认情况下创建就自动注册。
  • 支持服务端渲染(SSR)。
  • 支持 Vue DevTools
  • 更友好的代码分割机制,传送门。

Pinia 配套有个插件 pinia-plugin-persist进行数据持久化,否则一刷新就会造成数据丢失


本文摘录自:

  • 2022(金三银四)-vue3面试题汇总
  • vue3.0 响应式原理(超详细)
  • 「2022」打算跳槽涨薪,必问面试题及答案——VUE3 篇 -纯干货!图解Vue响应式原理
  • Vue3.0通关秘籍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2177574.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux基础IO】Linux IO编程入门:揭秘动态库与静态库的秘密

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:Linux “ 登神长阶 ” 🤡往期回顾🤡:Linux Shell 🌹🌹期待您的关注 🌹🌹 ❀Linux基础IO 📒1. …

Mysql梳理10——使用SQL99实现7中JOIN操作

10 使用SQL99实现7中JOIN操作 10.1 使用SQL99实现7中JOIN操作 本案例的数据库文件分享: 通过百度网盘分享的文件:atguigudb.sql 链接:https://pan.baidu.com/s/1iEAJIl0ne3Y07kHd8diMag?pwd2233 提取码:2233 # 正中图 SEL…

Git 的安装和配置

Git 是跨平台的,可以在 Windows,Linux、Unix 和 Mac 各几大平台上使用 由于笔者主要是使用 Windows,其他平台下安装 Git 的方法暂且不表(可参考廖雪峰老师的博客:安装 Git) ‍ Windows 安装 Git 从 Git…

【案例73】Uclient无法读取https地址添加应用

问题现象 客户做了一个https的域名转换,网页端是正常访问的,但是在uclient里面添加应用就不行了,出来两个不对的应用,也安装不了,提示失败。 问题分析 点击添加应用发现,本来添加地址是https://域名:外网端口&#x…

【C++报错已解决】std::bad_alloc

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 专栏介绍 在软件开发和日常使用中,BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

海外媒体投稿:如何运用3种国内外媒体套餐发稿突出重围?

在当今瞬息万变的经营环境中,突出重围营销推广是每家企业都需要思考的问题。为了能突出重围并提升影响力,国内外媒体套餐内容成为了一个非常受欢迎的挑选。下面我们就为大家讲解如何运用三种不同种类的国内外媒体套餐内容来推广突出重围。 2.微博营销新浪…

GIS在构建虚拟世界中的新机遇

地理信息系统(GIS)技术在构建虚拟世界中扮演着越来越重要的角色。随着数字孪生、虚拟现实(VR)、增强现实(AR)和混合现实(MR)等技术的发展,GIS为虚拟世界提供了地理信息和…

QT开发:基于Qt实现的交通信号灯模拟器:实现一个带有倒计时功能的图形界面应用

介绍 本文将介绍如何使用Qt框架实现一个简单的交通信号灯控制程序。本程序包括一个图形界面,显示红、黄、绿三色信号灯,并通过定时器控制信号灯的切换。同时,我们还将实现一个带有按钮的界面,用于展示信号灯的状态。 1. 安装Qt开…

Linux下的git开篇第一文:git的意义

目录 1.git版本控制器 2.git gitee&&github 3.Linux中gitee的使用 ( 三板斧 git add git commit -m " " git push ) 4.git log 查看之前的修改信息 (所有提交日志) 5.git status 查看工作目录与本地…

三防手机也能实现双卫星通信?智慧应急再添一员猛将!

随着可重复使用运载火箭技术取得显著进展,民营航天快速发展,商业卫星的发射成本不断降低,卫星通信全面普及的时代即将来临。遨游通讯提前布局双卫星通信技术,AORO M5-5G三防手机集成了天通卫星电话与北斗短报文两大国产通信技术。…

怎么将excel表格数据自动生成二维码?批量静态二维码转换的方法

在日常生活中,遇到需要大量二维码制作需求时,比如说需要给同一批产品生成不同编号的二维码时,有什么方法能够快速批量生成二维码呢?如果一个个二维码去制作不仅需要浪费大量的时间,而且也比较容易出错,那么…

MATLAB读取TIF文件,并可视化

在GIS领域,TIF文件则常用于存储地图、地形图等地理空间数据,TIF文件用于地理信息系统时,它通常包含地理坐标、投影信息等地理元数据,这些元数据使得图像能够与地理信息系统无缝集成,便于进行地理定位和分析。 1.读取T…

初始C++模板

1.泛型编程 1.1什么事泛型编程 在学习C语言时,我们时常会有这样的烦恼: 在针对每一种不同的类型变量进行函数传参或者是运算处理时,我们总是编写不同的函数或者是进行不同的处理,才能达到目的,这时,我们…

【JavaEE初阶】深入解析单例模式中的饿汉模式,懒汉模式的实现以及线程安全问题

前言: 🌈上期博客:【JavaEE初阶】深入理解wait和notify以及线程饿死的解决-CSDN博客 🔥感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 ⭐️小编会在后端开发的学习中不断更新~~~ 🥳非常感谢你的…

YOLOv8改进 - 注意力篇 - 引入LSKA注意力机制

一、本文介绍 作为入门性篇章,这里介绍了LSKA注意力在YOLOv8中的使用。包含LSKA原理分析,LSKA的代码、LSKA的使用方法、以及添加以后的yaml文件及运行记录。 二、LSKA原理分析 LSKA官方论文地址:LSKA文章 LSKA注意力机制(大可分…

胤娲科技:揭秘AI记忆宫殿—LLM如何用动画玩转乔丹打篮球的秘密

当AI遇上“乔丹打篮球”,真相竟然藏在动画里? 想象一下,你向一位AI大模型轻声询问:“迈克尔・乔丹从事的体育运动是……”几乎在瞬间,它就自信满满地回答:“篮球!” 这一刻,你是否曾…

ROS理论与实践学习笔记——2 ROS通信机制之服务通信

服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。也即: 一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A,用于偶然的、对时时性有要求、有一定逻辑处理需求的数据传输…

电脑usb接口控制软件有哪些?六款软件帮你轻松管控USB端口!

小明(疑惑地):“小李,我们公司最近对数据安全特别重视,我听说可以通过软件来控制电脑的USB接口,防止数据泄露。你知道有哪些好用的USB接口控制软件吗?” 小李(自信地)&a…

双十一买什么好?五大双十一好物推荐!

每年的双十一购物节都是消费者期待已久的盛事,届时各大电商平台纷纷推出优惠活动,吸引了无数购物爱好者的目光。双十一买什么好?为了帮助大家在双十一期间高效购物,我们精心挑选了五大双十一好物推荐!这些产品不仅在品…

C++之STL—函数对象谓词

函数对象(仿函数) 函数对象(仿函数)是一个**类**,不是一个函数 类名() 仿函数 直接调用: 、 谓词 定义:返回类型为bool 类型的仿函数 一元谓词:operator()接受一个参数 二元谓词&a…