vue2025前端面试题

380 阅读11分钟

1. vue2和vue3的区别

  1. 响应式系统不同:Vue 2 使用 Object.defineProperty 实现响应式,存在一些限制,比如不能检测到数组索引和对象的新增属性。而 Vue 3 使用 Proxy 实现响应式,更加灵活,性能也更好,能处理更多复杂的数据结构。
  2. 组合方式不同:Vue 2 使用 Options API(如 data、methods、computed 等)来组织代码;Vue 3 引入了 Composition API,通过 setup() 函数、ref、reactive 等方式来组合逻辑,使得复杂组件的逻辑更清晰、更易于复用。
  3. 性能更优:Vue 3 在编译和运行时都有优化,体积更小,渲染更快,并且支持 Tree-shaking,可以只引入用到的功能,减少打包体积。
  4. TypeScript 支持更好:Vue 3 是用 TypeScript 编写的,对 TypeScript 有更好的内建支持,而 Vue 2 对 TS 的支持较弱。
  5. 模板改进:Vue 3 支持 Fragment(多个根节点)、Teleport(跨层级渲染)、Suspense(异步组件加载时的占位)等新特性,使模板编写更加灵活。
  6. 生命周期钩子不同:Vue 3 的 Composition API 使用如 onMounted、onUnmounted 等钩子函数替代了 Vue 2 的 mounted、destroyed 等生命周期选项,命名更统一,也便于逻辑复用。

Vue2 的响应式原理

  • 核心:Object.defineProperty + 观察者模式****
  • 实现机制:
    1. Vue 在初始化数据时,会遍历 data 的每个属性,用 Object.defineProperty 把它们转成 getter/setter。
    2. 当访问属性时,getter 会收集依赖(记录哪些组件/Watcher 用到了这个数据)。
    3. 当修改属性时,setter 会通知依赖更新,触发视图重新渲染。
  • 缺点:
    • 不能监听对象属性的新增/删除(需要 Vue.set / Vue.delete)。
    • 数组部分方法(如直接通过索引修改)无法触发更新(需要用变异方法 push、splice 等)。

Vue3 的响应式原理

  • 核心:ES6 的 Proxy + Reflect****
  • 实现机制:
    1. Vue3 使用 Proxy 拦截对象的读取、修改、删除操作。
    2. 通过 Reflect.get/set/deleteProperty 实现依赖收集和触发更新。
    3. 可以直接监听 新增/删除属性数组索引修改Map/Set 等新数据结构
  • 优点:
    • 解决了 Vue2 的缺陷。
    • 性能更好,逻辑更清晰。
    • 响应式系统可独立使用(@vue/reactivity 包)。

2. watch和watch effect的区别

  1. 使用方式不同
    • watch 需要指定要监听的具体数据源(可以是一个 ref、reactive 属性或 getter 函数)。
    • watchEffect 不需要显式指定监听目标,它会自动收集在回调中使用到的所有响应式数据。
  2. 执行时机不同
    • watch 默认是懒执行的,只有被监听的数据变化时才会执行回调。
    • watchEffect 会在组件创建时立即执行一次回调,然后在依赖变化时再次执行。
  3. 应用场景不同
    • 用 watch 更适合监听特定数据的变化,比如监听某个 prop、路由参数变化。
    • 用 watchEffect 更适合进行一些依赖多个响应式数据的副作用处理,比如自动跟踪逻辑或简化一些复杂的 watch 写法。

3. watch和computed的区别

作用不同

  • computed 是用于声明一个计算属性,通常用于从已有数据中派生出新的值,结果会被缓存,只有相关依赖发生变化时才重新计算。
  • watch 是用于观察某个数据变化时,执行某些副作用逻辑(如异步请求、打印日志等),不会返回一个值。

是否有返回值

  • computed 是有返回值的,你可以把它当作一个值来使用(例如模板中显示)。
  • watch 没有返回值,它只是监听数据变化后执行回调函数

是否缓存

  • computed 会缓存结果,依赖数据没变时不会重复计算。
  • watch 没有缓存,每次数据变化都会执行回调。

4. watch监听多个值

方法是传入一个数组或一个返回多个值的函数

5. watch想要马上执行

immediate: true

6. watch深度监听对象

deep: true

7. echarts数据改变了,但是图表没改变

myChart.setOption(option, true); // 第二个参数为 true,表示覆盖旧配置

8. vue中数组改变 但是视图没更新

// 方法 1:使用 Vue.set
this.$set(this.items, 1, 'new value');

// 方法 2:替换整个数组(触发响应)
this.items = [...this.items.slice(0, 1), 'new value', ...this.items.slice(2)];

9. vue中如果自己封装组件,子组件怎么改变父组件的值

10. ref和reactive的区别

 **作用对象不同**:
    -   ref 用来包装一个**基本类型的值**(如数字、字符串、布尔值)或者对象,生成一个响应式的对象,访问时要通过 .value。
    -   reactive 用来包装一个**对象(Object)或者数组**,返回的是一个响应式的代理对象,直接访问属性即可。
 **访问方式不同**:
    -   ref 包装的值通过 .value 访问和修改。
    -   reactive 返回的对象直接访问和修改属性。
 **适用场景不同**:
    -   当需要对一个基本类型值做响应式处理时,使用 ref。
    -   当需要对一个复杂对象或数组做响应式处理时,使用 reactive。

 **响应式实现不同**:
    -   ref 是通过一个包含 .value 属性的对象包装值。
    -   reactive 是通过 Proxy 实现对整个对象的深度响应式。

* * *

11. ref为什么能定义基本类型和对象

  • ref 是一个容器对象,它把任何值(基本类型或对象)都放到 .value 属性里。
  • 对于对象,.value 是响应式的代理对象(类似 reactive),可以深度响应。
  • 对于基本类型,.value 就是普通值,但包裹在对象中,方便 Vue 跟踪变化。

12. es6和es7

13. promise和async await

特点Promiseasync/await
语法形式链式回调 .then().catch()同步写法,使用 async 和 await
可读性相对复杂,特别是多个嵌套更清晰,接近同步代码
错误处理.catch() 捕获错误try/catch 捕获错误
执行顺序通过链式执行通过等待异步操作
兼容性ES6 支持较广ES2017,现代环境支持好

14.路由中 history和hush的区别

### **1. hash 模式(基于 URL 的 hash)**

-   URL 里带 # 符号,比如:

    http://example.com/#/about

-   工作原理:监听浏览器地址栏的 hash 变化(window.location.hash),不会向服务器发送请求。

-   特点:

    -   不需要服务器配置,兼容性好
    -   URL 中有 #,不美观
    -   页面刷新时,浏览器不会向服务器请求不同路径,只请求主页面

* * *

### **2. history 模式(基于 HTML5 History API)**

-   URL 是正常的路径,比如:

    http://example.com/about

-   利用浏览器的 history.pushState 和 popState 来实现路由跳转,地址栏路径看起来更干净。

-   特点:

    -   URL 更加美观,没有 #
    -   需要服务器配置,将所有路径都指向 index.html,防止刷新 404
    -   兼容性稍差,IE9 以下不支持(但现代浏览器都支持)

14.vue中key的作用

  1. 唯一标识节点****

    key 赋给列表中每个节点一个独一无二的标识,Vue 通过这个标识来判断节点是否发生变化,而不是简单靠顺序比较。

  2. 提升渲染性能****

    当数据更新时,Vue 会用 key 来复用、移动、删除和添加元素,避免不必要的重新渲染和 DOM 操作。

  3. 防止渲染错误****

    如果没有合理的 key,Vue 默认用就地复用策略,可能导致组件状态错乱,比如输入框输入内容错位、动画异常等。

15、v-for可以用index作为索引吗?

  • 语法上是允许的,Vue 不会报错。

  • 适合列表不会发生增删改,且顺序不变的简单场景。

  • 为什么不推荐用

  • 当列表发生增删改操作时,用 index 作为 key 会导致 Vue 误判节点,产生错误复用,可能出现:

    • 组件状态错乱
    • 输入框内容错乱
    • 动画异常等

16、vue中data为什么是个函数

在 Vue 中,data 必须是函数而非对象,主要是为了避免组件复用导致的数据共享问题

核心原因:组件复用与数据独立性

  • 对象是引用类型:如果 data 是对象,所有组件实例将共享同一份数据引用。当一个实例修改数据时,其他实例也会同步变化,导致数据污染。
  • 函数返回新对象:每个组件实例调用 data() 时返回独立的对象副本,确保数据相互隔离。

17、mvvm和mvm的区别?

MVVM 和 MVM 是两种不同的软件架构模式,核心区别在于架构层次的划分和职责分工:

  1. MVVM(Model-View-ViewModel)
    是主流的前端架构模式(如 Vue、React 常用),包含四层清晰分工:

    • Model:数据模型(后端数据或本地数据)
    • View:视图(UI 界面,用户能看到的部分)
    • ViewModel:连接 View 和 Model 的中间层,处理业务逻辑,双向绑定数据
    • 核心特点:View 与 ViewModel 通过数据绑定联动,开发者无需手动操作 DOM,专注逻辑。
  2. MVM(Model-View-Model)
    并非通用标准模式,可能是某些场景下的简化或变种:

    • 通常去掉了 ViewModel 层,由 View 直接与 Model 交互,或两个 Model 层分别处理不同数据逻辑
    • 特点:层次更简单,但 View 和 Model 耦合度可能更高,适合简单场景。

简单说,MVVM 是分层清晰、解耦彻底的成熟模式,而 MVM 是更简化的架构,应用范围较窄。前端开发中,MVVM 是主流选择(如 Vue 的响应式系统就是典型实现)。

18、跨域有哪几种解决方案?

  1. CORS(跨域资源共享)
    最标准、推荐的方式,由服务器配置响应头(如 Access-Control-Allow-Origin)允许指定域名跨域,支持所有 HTTP 方法,安全性高。
  2. JSONP
    利用 <script> 标签不受同源限制的特性,通过动态创建脚本标签请求数据,仅支持 GET 方法,适合兼容旧浏览器。
  3. 代理服务器
    前端请求同域的代理服务器,由代理转发请求到目标跨域服务器(如 Vue 项目的 vue.config.js 配置 devServer.proxy),开发环境常用。
  4. iframe 相关方案
    如 postMessage 实现 iframe 与父页面跨域通信,适用于页面嵌套场景。
  5. WebSocket
    建立持久连接后可跨域通信,适合实时交互场景(如聊天、弹幕)。

实际开发中,优先用 CORS(生产环境)或 代理服务器(开发环境),JSONP 仅作为兼容方案。

19、你对vue的生命周期是如何理解的?

🔹 1. 什么是 Vue 生命周期?

Vue 生命周期就是 一个组件从创建到销毁的整个过程,Vue 在不同阶段提供了钩子函数,开发者可以在这些钩子里写逻辑。

🔹 2. Vue 2.x 生命周期钩子

主要分四个阶段:

  1. 创建阶段****
    • beforeCreate:实例刚初始化,还没 data 和 props。
    • created:data/props 已经可以用了,但还没挂载 DOM。
  2. 挂载阶段****
    • beforeMount:模板已编译,还没渲染到页面。
    • mounted:页面渲染完成,可以访问 DOM。
  3. 更新阶段(数据变化 → 重新渲染)
    • beforeUpdate:数据更新了,但 DOM 还没更新。
    • updated:DOM 已经更新。
  4. 销毁阶段****
    • beforeDestroy:实例销毁前,可以清理定时器/事件。
    • destroyed:实例已经销毁。
🔹 3. Vue 3.x 生命周期(组合式 API)

Vue 3 里如果用 setup,生命周期钩子变成了 onXxx 的形式:

  • onBeforeMount
  • onMounted
  • onBeforeUpdate
  • onUpdated
  • onBeforeUnmount
  • onUnmounted 而 beforeCreate、created 这两个被合并进了 setup() 里,因为 setup 就是初始化逻辑。
🔹 4. 常见使用场景
  • created / setup:获取路由参数、初始化请求。
  • mounted / onMounted:操作 DOM、初始化第三方插件(比如 echarts)。
  • beforeUpdate:数据改动前做一些计算或记录。
  • updated:数据更新后依赖 DOM 的逻辑。
  • beforeUnmount / unmounted:清理定时器、移除事件监听
🔹 5. 总结理解
  • 生命周期就是 组件不同阶段的钩子,让我们有机会在合适的时机做合适的事。
  • Vue2 和 Vue3 差别主要是:
    • Vue2 是选项式 API(created/mounted 等)。
    • Vue3 是组合式 API(setup + onMounted/onUnmounted 等)。

20、从输入url到页面加载的过程?

  1. 浏览器会先进行 DNS 解析,把域名转成 IP。
  2. 然后通过 TCP 三次握手 建立连接,如果是 HTTPS 还要做 TLS 握手。
  3. 建立连接后浏览器发送 HTTP 请求,服务器接收并返回响应。
  4. 浏览器拿到响应内容后会进行 解析渲染:构建 DOM 树、CSSOM 树,合成渲染树,最后绘制页面。
  5. 在这个过程中还会执行 JS 脚本,处理异步请求和 DOM 更新。
  6. 最终用户看到完整的页面。