我的小厂面试复盘:这些Vue基础题你都能答对吗?

96 阅读4分钟

波珠的第一场前端面试,小厂,问的都是基础,但是波珠太菜了,八股背的不够多不够熟 准备不够充分,面得很烂,下面是正文

预览部分:

笔试:toRefs,vue怎么加载更快,keep-alive怎么缓存,$nextTick,ref和reactive区别,深拷贝浅拷贝区别,深拷贝怎么实现

面试:自我介绍,用three.js做数据大屏数据属性是怎么交互的,vue2和vue3生命周期区别,vue3项目一般做什么,开源主要做了啥,对象能用ref吗?怎么实现,vite和webpack区别,职业发展规划

一.toRefs

答案:.toRefs 是 Vue 3 提供的工具方法,用于将响应式对象的每个属性转成独立的 ref,解决 解构后丢失响应式 的问题

简单示例:

import { reactive, toRefs } from 'vue'const state = reactive({ count: 0, name: '鼠鼠' })
const { count, name } = toRefs(state)
​
count.value++ // 响应式正常工作

如果直接解构 reactive 对象:

const { count } = state
count++ //  失去响应式

ref → 一个值响应式

reactive → 整个对象响应式

toRef → 单个属性响应式

toRefs → 批量属性响应式

二.vue怎么加载更快

记忆口诀:"三减两压一缓存"

三减:减少首屏体积(路由懒加载、按需引入、CDN)

两压:压缩 JS/CSS + 图片压缩(Gzip/webp)

一缓存:浏览器缓存 + HTTP 缓存

三.keep-alive怎么缓存

答案:keep-alive 通过缓存组件实例 + LRU 策略,在切换组件时复用已渲染的实例,提升性能并保留状态

解释理解:

LRU机制:当缓存数量超出 max,会删除最久未使用的组件实例

生命周期普通组件keep-alive 组件
挂载created → mountedcreated → mounted
切换隐藏beforeUnmount → unmounteddeactivated(组件被缓存,但未真正卸载)
切换激活重新执行 mountedactivated(组件从缓存中被激活)

四.$nextTick

答案:$nextTick 用于在 DOM 更新完成后 立即执行回调函数,保证拿到最新的 DOM 状态

解释理解:

  • Vue 的 响应式更新是异步批处理 ,当数据变化时,Vue 不会立即更新 DOM,而是开启一个任务队列
  • 在当前事件循环结束后,统一执行 DOM 更新,避免频繁操作 DOM 造成性能浪费
  • Vue 内部实现 $nextTick 使用了 微任务优先、宏任务兜底 的机制,保证了 $nextTick 回调总是在 DOM 更新后立刻执行,而且内部使用Promise.resolve().then(),执行顺序比普通的 setTimeout 更快

五.ref和reactive区别

ref 适合处理 基本类型 或单个值,通过 .value 访问。

reactive 适合处理 对象或数组,返回的是一个 Proxy 代理对象,可直接访问属性。

特性refreactive
数据类型基本类型、对象都可仅对象、数组、集合类型
访问方式通过 .value 访问直接访问属性
底层原理基本类型用 value 包装,内部调用 reactive 处理对象通过 Proxy 代理整个对象
使用场景单值状态、标志位复杂对象、表单、列表数据

六.深拷贝浅拷贝区别,深拷贝怎么实现

特性浅拷贝深拷贝
拷贝层级只拷贝一层递归拷贝所有层级
引用类型影响修改子对象会互相影响完全独立互不影响
性能高(不递归,简单)低(递归遍历,耗性能)

浅拷贝的实现

Object.assign() 或 扩展运算符 {...obj}

深拷贝的实现

方法一:JSON.parse(JSON.stringify())

最简单直接,但是会丢失 undefinedSymbol函数,无法处理循环引用,报错

JSON.stringify() 用于把对象序列化成 JSON 字符串JSON.parse() 用于将 JSON 字符串反序列化为对象;结合使用时,相当于先把对象“拍扁”,再重建一个新对象,从而实现深拷贝

const obj = { a: 1, b: { c: 2 }, d: undefined, e: () => {} };
const copy = JSON.parse(JSON.stringify(obj));
console.log(copy); 
// { a: 1, b: { c: 2 } }  // undefined 和函数丢失

方法二:递归拷贝

可处理循环引用,可保留复杂数据类型;实现复杂,要考虑多种复杂对象如Set的情况

方法三:structuredClone()(推荐)

性能好,能拷贝MapSet等复杂结构,能处理循环引用;兼容性不足(Node 17+,Chrome 98+)

const obj = { a: 1, b: { c: 2 } };
const copy = structuredClone(obj);
copy.b.c = 3;
console.log(obj.b.c); // 2 

方法四:第三方库 lodash.cloneDeep()

可靠性高;需要引入第三方库,增加包体积

import cloneDeep from 'lodash/cloneDeep';
const copy = cloneDeep(obj);

七.three.js做数据大屏数据属性是怎么交互的

在 three.js 数据大屏中,通过 数据绑定到三维模型,结合 Raycaster 进行交互检测,并实时更新 positionscalecolor 等属性,使用动画库实现平滑过渡,最终形成实时、动态、可交互的三维可视化场景。 同时,利用实例化渲染和分层更新等优化手段,保证大屏性能流畅。

八.vue2和vue3生命周期区别

Vue 3 所有生命周期函数都加 on 前缀,destroyunmount

阶段Vue 2Vue 3 (组合式 API)
创建前beforeCreate无对应 → 逻辑可放在 setup 顶部
创建后created无对应 → 逻辑可放在 setup 顶部
挂载前beforeMountonBeforeMount
挂载后mountedonMounted
更新前beforeUpdateonBeforeUpdate
更新后updatedonUpdated
销毁前beforeDestroyonBeforeUnmount
销毁后destroyedonUnmounted
错误捕获errorCapturedonErrorCaptured
新钩子onRenderTracked / onRenderTriggered

九.对象能用ref吗?怎么实现

能,ref包裹对象时内部会使用 reactive 处理对象,使其深层属性响应式。

实现方式:

import { ref } from 'vue'const state = ref({ count: 0 }) // 对象也可以用 ref
state.value.count++ // 修改对象属性需要通过 value

十.vite和webpack区别

特性WebpackVite
启动速度启动慢,需要先打包整个项目启动快,按需编译,直接基于 ESM
热更新 (HMR)需重新打包依赖链,速度较慢直接替换模块文件,毫秒级更新
开发原理运行前必须构建一个打包产物浏览器原生支持 ESM,未访问的文件不编译
生产构建自己实现打包基于 Rollup,优化 Tree-shaking
生态成熟度生态最完善,插件丰富生态逐渐完善,但整体比 Webpack 新
配置复杂度配置繁琐,学习曲线陡峭配置简单,开箱即用
适合场景复杂项目、大型企业项目中小型项目、快速原型开发

简单记:

Vite 开发快 → 原生 ESM + 按需编译

Webpack 构建强 → 生态成熟 + 插件丰富

开发选 Vite,兼容选 Webpack