Vue面试——高频题之vue基础

121 阅读22分钟

1.Vue的基本原理 (数据双向绑定的基本原理)

Vue.js 的核心原理是通过 数据劫持 结合 发布者-订阅者模式,实现数据和视图的双向绑定。以下是其基本原理的详细说明:

1. 数据劫持(Observer)

Vue.js 在实例化时,会遍历 data 对象的所有属性,并使用 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)将这些属性转换为 gettersetter。当属性被访问或修改时,gettersetter 会被触发,从而实现对数据的监听。

依赖收集:在 getter 中,Vue 会收集当前属性的依赖(即哪些视图或组件依赖于该属性)。

变更通知:在 setter 中,当数据发生变化时,Vue 会通知所有依赖该属性的订阅者(Watcher)进行更新。

图表说明:

+-------------------+
| 数据对象 (Data)   |
| - 属性1: getter   |
| - 属性2: setter   |
+-------------------+
         |
         v
+-------------------+
| 监听器 (Observer) |
| - 依赖收集        |
| - 变更通知        |
+-------------------+

2. 模板编译(Compile)

Compile 负责解析模板指令,将模板中的变量替换为数据,并初始化渲染页面视图。同时,它为每个指令对应的节点绑定更新函数,并添加监听数据的订阅者(Watcher)。

指令解析:解析模板中的 v-modelv-bind 等指令。

数据绑定:将模板中的变量与数据对象关联,并初始化视图。

更新函数绑定:为每个指令对应的节点绑定更新函数,以便在数据变化时更新视图。

图表说明:

+-------------------+
| 模板 (Template)   |
| - 指令解析        |
| - 数据绑定        |
+-------------------+
         |
         v
+-------------------+
| 编译器 (Compile)  |
| - 初始化视图      |
| - 绑定更新函数    |
+-------------------+

3. 订阅者(Watcher)

WatcherObserverCompile 之间的桥梁,主要负责以下任务:

  1. 依赖收集:在实例化时,将自身添加到属性订阅器(Dep)中。
  2. 更新视图:当数据变化时,Dep 会通知 WatcherWatcher 调用 update() 方法,触发 Compile 中绑定的回调,完成视图更新。

图表说明:

+-------------------+
| 订阅者 (Watcher)  |
| - 依赖收集        |
| - 更新视图        |
+-------------------+
         ^
         |
+-------------------+
| 属性订阅器 (Dep)  |
| - 管理订阅者      |
| - 通知变更        |
+-------------------+

4. MVVM 架构

MVVM 作为数据绑定的入口,整合了 ObserverCompileWatcher 三者的功能,实现了数据变化到视图更新、视图交互变化到数据 Model 变更的双向绑定。

图表说明:

+-------------------+
| MVVM 架构         |
| - Observer        |
| - Compile         |
| - Watcher         |
+-------------------+
         ^
         |
+-------------------+
| 视图 (View)       |
| - 自动更新        |
+-------------------+
         ^
         |
+-------------------+
| 数据 (Model)      |
| - 自动同步        |
+-------------------+

总结

Vue.js 的响应式系统通过 数据劫持模板编译订阅者模式MVVM 架构,实现了数据和视图的双向绑定。这种机制确保了数据变化时视图自动更新,同时视图交互也能反映到数据的变化中,极大地简化了开发流程。

4. MVVM、MVC、MVP的区别

MVC、MVP 和 MVVM 是三种常见的软件架构设计模式,主要通过分离关注点的方式来组织代码结构,优化开发效率。以下是它们的详细区别:


1. MVC(Model-View-Controller)

MVC 通过分离 Model、View 和 Controller 的方式来组织代码结构:

  • Model:负责存储页面的业务数据,以及对相应数据的操作。
  • View:负责页面的显示逻辑。
  • Controller:是 View 和 Model 之间的纽带,主要负责用户与应用的响应操作。当用户与页面产生交互时,Controller 中的事件触发器开始工作,通过调用 Model 层来完成对 Model 的修改,然后 Model 层再去通知 View 层更新。

核心细节

  • 数据流向:用户操作 → Controller → Model → View。
  • 优点:结构简单,适合小型项目。
  • 缺点:Controller 臃肿,View 和 Model 耦合度高,难以复用和测试。

图表说明:

+-------------------+
| MVC 架构          |
| - Model           |
| - View            |
| - Controller      |
+-------------------+

2. MVP(Model-View-Presenter)

MVP 模式与 MVC 的主要区别在于 Presenter 和 Controller: • Model:负责数据的处理和业务逻辑。 • View:负责展示数据给用户,并处理用户的输入。 • Presenter:协调 Model 和 View 之间的交互,处理用户的输入并更新 Model 和 View。

核心细节: • 数据流向:用户操作 → View → Presenter → Model → Presenter → View。 • 优点:View 和 Model 解耦,职责划分明确,便于测试。 • 缺点:接口冗余,Presenter 层可能变得臃肿。

图表说明:

+-------------------+
| MVP 架构          |
| - Model           |
| - View            |
| - Presenter       |
+-------------------+

3. MVVM(Model-View-ViewModel)

MVVM 分为 Model、View 和 ViewModel: • Model:代表数据模型,数据和业务逻辑都在 Model 层中定义。 • View:代表 UI 视图,负责数据的展示。 • ViewModel:负责监听 Model 中数据的改变并且控制视图的更新,处理用户交互操作。

核心细节: • 数据流向:用户操作 → View → ViewModel → Model → ViewModel → View(通过数据绑定自动更新)。 • 优点:通过双向数据绑定实现 Model 和 View 的自动同步,开发者无需手动操作 DOM。 • 缺点:学习成本较高,过度绑定可能导致逻辑分散。

图表说明:

+-------------------+
| MVVM 架构         |
| - Model           |
| - View            |
| - ViewModel       |
+-------------------+

总结

MVC:适合小型项目,但 Controller 臃肿,难以复用和测试。

MVP:解决了 MVC 中 View 和 Model 耦合的问题,但接口冗余。

MVVM:通过双向数据绑定实现自动同步,适合中大型项目,但学习成本较高。

5. Computed 和 Watch 的区别

在 Vue.js 中,computedwatch 都是用于监听数据变化的工具,但它们的适用场景和实现方式有所不同。以下是它们的详细区别:


1. Computed(计算属性)

computed 是用于计算属性值的,它的核心特点是基于依赖的缓存机制。

缓存机制:只有当依赖的数据发生变化时,computed 才会重新计算。

同步操作:不支持异步操作,无法在 computed 中直接使用异步逻辑。

默认行为computed 的值会默认走缓存,基于响应式依赖(如 dataprops 中的数据)进行计算。

使用场景:适合用于依赖其他属性计算而来的属性,例如通过多个属性计算出一个结果。

方法

getter:默认使用 get 方法,函数的返回值就是属性的值。

setter:可以通过 set 方法设置值,当数据变化时会调用 set 方法。

图表说明:

+-------------------+
| Computed          |
| - 缓存机制        |
| - 同步操作        |
| - 基于依赖计算    |
+-------------------+

2. Watch(侦听器)

watch 是用于监听数据变化的,它的核心特点是实时响应数据变化并执行回调。

无缓存机制:数据变化时,watch 会立即触发相应的操作。

支持异步:可以在 watch 中执行异步操作,例如访问 API。

参数:监听函数接收两个参数,第一个是最新值,第二个是变化前的值。

使用场景:适合用于需要执行异步或开销较大的操作,例如在数据变化时调用 API。

配置选项

  • immediate:组件加载时立即触发回调函数。
  • deep:深度监听,可以监听到复杂数据类型(如对象或数组)内部的变化。

图表说明:

+-------------------+
| Watch             |
| - 无缓存机制      |
| - 支持异步        |
| - 实时响应        |
+-------------------+

3. 对比与总结

特性ComputedWatch
缓存机制支持缓存,依赖变化时重新计算无缓存,数据变化时立即触发
异步支持不支持异步支持异步
适用场景依赖其他属性计算值数据变化时执行异步或复杂操作
参数无参数接收最新值和变化前的值
配置选项immediatedeep

4. 运用场景

  • 使用 computed

    • 当需要进行数值计算,并且依赖于其他数据时。
    • 当需要缓存计算结果,避免重复计算时。
  • 使用 watch

    • 当需要在数据变化时执行异步操作(如调用 API)。
    • 当需要监听复杂数据类型内部的变化时。

总结

computed:适合用于依赖其他属性计算值的场景,具有缓存机制,性能更优。

watch:适合用于需要实时响应数据变化并执行异步或复杂操作的场景,灵活性更高。

6. Computed 和 Methods 的区别

可以将同一函数定义为一个 method 或者一个计算属性。对于最终的结果,两种方式是相同的

不同点:

  • computed: 计算属性是基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值;
  • method 调用总会执行该函数。

13. v-if 和 v-show 的区别

在 Vue.js 中,v-ifv-show 都用于控制元素的显示与隐藏,但它们的实现方式和适用场景有所不同。以下是它们的详细区别:


1. ​实现手段

  • v-if:动态地向 DOM 树中添加或删除元素。当条件为 false 时,元素会被完全移除;当条件为 true 时,元素会被重新创建并插入 DOM。
  • v-show:通过设置元素的 display 样式属性来控制显隐。当条件为 false 时,元素会被隐藏(display: none);当条件为 true 时,元素会显示(display: 正常值)。

2. ​编译过程

  • v-if:在切换过程中,会有一个局部编译/卸载的过程。当条件为 false 时,元素及其事件监听器和子组件会被销毁;当条件为 true 时,元素会被重新编译和挂载。
  • v-show:只是简单地基于 CSS 进行切换,元素始终存在于 DOM 中,不会触发编译或卸载过程。

3. ​编译条件

  • v-if:是惰性的。如果初始条件为 false,则什么也不做;只有在条件第一次变为 true 时,才会开始局部编译。
  • v-show:无论初始条件是否为 true,元素都会被编译并缓存,DOM 元素始终保留。

4. ​性能消耗

  • v-if:有更高的切换消耗,因为每次切换都会触发元素的销毁和重建。
  • v-show:有更高的初始渲染消耗,因为元素始终存在于 DOM 中,但切换时只需要修改 display 属性,性能开销较小。

5. ​使用场景

  • v-if:适合用于条件不太可能频繁变化的场景,例如根据用户权限显示不同的内容。
  • v-show:适合用于需要频繁切换的场景,例如选项卡或折叠面板。

6. ​对比总结

特性v-ifv-show
实现手段动态添加/删除 DOM 元素修改 display 样式属性
编译过程有编译/卸载过程简单 CSS 切换
编译条件惰性,条件为 true 时编译始终编译并缓存
性能消耗切换消耗高初始渲染消耗高
使用场景条件不频繁变化频繁切换

总结

  • v-if:适合用于条件不频繁变化的场景,但切换时性能开销较大。
  • v-show:适合用于需要频繁切换的场景,但初始渲染时性能开销较大。

16. data 为什么是一个函数而不是对象

在 Vue.js 中,data 选项通常被定义为一个函数而不是一个对象。这是因为 JavaScript 中的对象是引用类型的数据,当多个实例引用同一个对象时,修改其中一个实例的数据会影响其他实例的数据。以下是详细解释:


1. ​对象是引用类型

在 JavaScript 中,对象是引用类型的数据。如果多个组件实例共享同一个对象,那么修改其中一个实例的数据会导致其他实例的数据也被修改。这种行为在 Vue.js 中是不期望的,因为 Vue.js 的设计理念是让每个组件实例都拥有独立的数据。


2. ​组件的复用性

Vue.js 的核心思想之一是组件的复用性。为了确保每个组件实例都拥有自己的独立数据,data 必须是一个函数。每次复用组件时,data 函数会返回一个新的对象,这样每个组件实例都会维护自己的私有数据空间,而不会干扰其他组件的正常运行。


3. ​数据隔离

通过将 data 定义为一个函数,可以确保每个组件实例都有自己的数据副本。这种隔离机制使得组件之间的数据不会相互影响,从而提高了代码的可维护性和可复用性。


4. ​示例对比

  • 错误写法(对象形式)​
    export default {
      data: {
        message: 'Hello, Vue!'
      }
    }
    这种写法会导致所有组件实例共享同一个 `data` 对象,修改一个实例的数据会影响其他实例。
    
    
  • 正确写法(函数形式)
    export default {
      data() {
        return {
          message: 'Hello, Vue!'
        }
      }
    }
    
    这种写法确保每次复用组件时,都会返回一个新的 data 对象,从而实现数据隔离。

总结

在 Vue.js 中,data 被定义为一个函数而不是对象,主要是为了解决对象引用类型数据共享的问题。通过将 data 定义为一个函数,可以确保每个组件实例都拥有自己的私有数据空间,从而实现组件之间的数据隔离,提高代码的可维护性和复用性。

28. 对 React 和 Vue 的理解,它们的异同

React 和 Vue 是目前最流行的两个前端框架,它们有许多相似之处,但也有一些关键的区别。以下是它们的详细对比:


相似之处

  1. 核心库专注
    两者都将注意力集中在核心库上,而将其他功能(如路由和全局状态管理)交给相关的库。

  2. 构建工具
    两者都有自己的构建工具,能够快速生成一个根据最佳实践设置的项目模板:

    • React:Create React App
    • Vue:vue-cli
  3. 虚拟 DOM
    两者都使用了虚拟 DOM(Virtual DOM)来提高重绘性能,减少直接操作真实 DOM 的开销。

  4. Props 概念
    两者都支持 props,允许组件之间的数据传递。

  5. 组件化
    两者都鼓励组件化应用,将应用拆分成一个个功能明确的模块,提高代码的复用性和可维护性。


不同之处

  1. 数据流

    • Vue:默认支持双向数据绑定(v-model),简化了表单处理等场景。
    • React:一直提倡单向数据流,数据从父组件传递到子组件,子组件通过回调函数通知父组件更新数据。
  2. 虚拟 DOM 的实现

    • Vue:在渲染过程中会跟踪每个组件的依赖关系,只重新渲染依赖发生变化的组件,不需要重新渲染整个组件树。
    • React:每当应用状态改变时,默认会重新渲染整个组件树,但可以通过 PureComponentshouldComponentUpdate 进行优化。
  3. 组件化与模板编写

    • Vue:鼓励使用近似常规 HTML 的模板,写起来接近标准 HTML 元素,只是多了一些属性。
    • React:推荐使用 JSX(JavaScript 语法扩展)来编写模板,所有模板都通过 JavaScript 实现。
    • 具体区别
      • React 的 render 函数支持闭包特性,import 的组件可以直接调用。
      • Vue 需要在 components 中声明 import 的组件。
  4. 监听数据变化的实现原理

    • Vue:通过 getter/setter 以及函数劫持,能够精确知道数据变化,不需要特别优化就能达到很好的性能。
    • React:默认通过比较引用的方式进行数据变化检测,如果不优化可能导致大量不必要的虚拟 DOM 重新渲染。
  5. 高阶组件与 Mixins

    • React:通过高阶组件(HOC)来扩展功能,组件本身就是纯粹的函数,因此高阶函数对 React 来说非常自然。
    • Vue:通过 mixins 来扩展功能,由于 Vue 使用 HTML 模板创建视图组件,无法有效编译,因此不支持高阶组件。
  6. 构建工具

    • ReactCreate React App
    • Vuevue-cli
  7. 跨平台

    • ReactReact Native 用于开发原生移动应用。
    • VueWeex 用于开发跨平台移动应用。

总结

  • 相似点:两者都专注于核心库,支持虚拟 DOM、组件化和 props,并提供了自己的构建工具。
  • 不同点
    • Vue 默认支持双向数据绑定,而 React 提倡单向数据流。
    • Vue 使用 HTML 模板,React 使用 JSX。
    • Vue 通过 getter/setter 监听数据变化,React 通过引用比较。
    • React 支持高阶组件,Vue 使用 mixins
    • React 有 React Native,Vue 有 Weex。 以下是 React 和 Vue 的对比图表,用于更直观地展示它们的异同:

React 和 Vue 的对比表

特性ReactVue
数据流单向数据流默认支持双向数据绑定(v-model
虚拟 DOM 实现默认重新渲染整个组件树跟踪依赖关系,只更新依赖组件
模板编写使用 JSX(JavaScript 语法扩展)使用近似 HTML 的模板
数据变化监听通过引用比较,需手动优化通过 getter/setter 自动监听
组件扩展方式高阶组件(HOC)Mixins
构建工具Create React Appvue-cli
跨平台支持React NativeWeex

总结

  • React:更适合需要高度灵活性和复杂状态管理的项目,适合熟悉 JavaScript 的开发者。
  • Vue:更适合需要快速上手和简单数据绑定的项目,适合初学者或偏好 HTML 模板的开发者。

29. Vue 的优点

Vue.js 是一个轻量级、易学易用的前端框架,具有许多独特的优势,使其成为开发者的热门选择。以下是 Vue 的主要优点:


1. ​轻量级框架

Vue 只关注视图层,是一个构建数据的视图集合,核心库的大小只有几十 KB。这使得 Vue 在性能和加载速度上具有显著优势,特别适合开发轻量级应用。


2. ​简单易学

Vue 由国人开发,拥有完善的中文文档,不存在语言障碍,易于理解和学习。其 API 设计简洁,学习曲线平缓,适合初学者快速上手。


3. ​双向数据绑定

Vue 保留了 Angular 的特点,支持双向数据绑定(通过 v-model)。这使得在表单处理和数据操作方面更为简单,开发者无需手动操作 DOM 即可实现数据的同步更新。


4. ​组件化

Vue 借鉴了 React 的优点,支持组件化开发。通过将 HTML、CSS 和 JavaScript 封装成可复用的组件,Vue 在构建单页面应用(SPA)方面具有独特的优势,提高了代码的复用性和可维护性。


5. ​视图、数据、结构分离

Vue 实现了视图、数据和结构的分离。开发者只需关注数据的变化,无需修改逻辑代码,数据的更改会自动更新视图。这种设计使得开发过程更加高效和直观。


6. ​虚拟 DOM

Vue 使用虚拟 DOM 来优化性能。虚拟 DOM 减少了直接操作真实 DOM 的开销,通过高效的 Diff 算法,只更新需要变化的部分,极大提升了渲染性能。


7. ​运行速度更快

相比 React,Vue 在操作虚拟 DOM 时性能更优。Vue 在渲染过程中会跟踪每个组件的依赖关系,只更新依赖发生变化的组件,而 React 默认会重新渲染整个组件树。这使得 Vue 在性能上具有明显优势。


对比图表

特性VueReact
轻量级核心库大小仅几十 KB核心库较大
学习曲线简单易学,中文文档完善学习曲线较陡,英文文档为主
数据绑定双向数据绑定(v-model单向数据流
组件化支持组件化,易于复用支持组件化,但语法更复杂
性能优化虚拟 DOM,依赖跟踪优化虚拟 DOM,默认重新渲染组件树
开发效率视图、数据、结构分离,开发高效需要手动优化性能,开发稍复杂

总结

Vue.js 凭借其轻量级、简单易学、双向数据绑定、组件化、视图数据分离、虚拟 DOM 和高效性能等优点,成为前端开发的热门选择。无论是初学者还是经验丰富的开发者,Vue 都能提供高效、灵活的解决方案。

37. 对 SPA 单页面的理解,它的优缺点分别是什么?

SPA(Single-Page Application,单页面应用)是一种现代 Web 应用架构,仅在页面初始化时加载相应的 HTML、JavaScript 和 CSS。之后的所有页面交互都通过 JavaScript 动态更新内容,而不会重新加载页面。以下是 SPA 的详细解析:


1. ​SPA 的工作原理

SPA 的核心思想是通过路由机制动态更新页面内容,而不是跳转到新的页面。具体过程如下:

  • 首次加载:加载 HTML、CSS 和 JavaScript 文件。
  • 后续交互:通过 AJAX 或 Fetch API 获取数据,利用 JavaScript 动态更新 DOM,实现页面内容的切换。

2. ​SPA 的优点

  • 用户体验好:页面内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染,提升了用户体验。
  • 服务器压力小:由于大部分页面逻辑和渲染都在客户端完成,服务器只需提供数据接口,减少了服务器的负载。
  • 前后端职责分离:前端负责交互逻辑,后端负责数据处理,架构清晰,便于开发和维护。

3. ​SPA 的缺点

  • 初次加载耗时多:为实现单页应用功能,需要在首次加载时将所有 JavaScript 和 CSS 文件加载完毕,导致初次加载时间较长。
  • 前进后退路由管理:由于所有内容都在一个页面中动态更新,浏览器的前进后退功能无法直接使用,需要开发者自行实现路由堆栈管理。
  • SEO 难度较大:由于页面内容是通过 JavaScript 动态生成的,搜索引擎爬虫难以抓取和索引内容,导致 SEO 效果较差。

对比图表

特性SPA传统多页面应用
页面加载仅首次加载,后续动态更新每次页面跳转都重新加载
用户体验流畅,无需重新加载页面每次跳转都有延迟
服务器压力较小,后端仅提供数据接口较大,后端需渲染和返回页面
初次加载时间较长,需加载所有资源较短,每次加载部分资源
路由管理需自行实现前进后退功能浏览器原生支持
SEO 支持较差,内容动态生成较好,内容静态生成

总结

SPA 通过动态更新页面内容,提供了流畅的用户体验和清晰的架构设计,但也存在初次加载时间长、路由管理复杂和 SEO 难度大等缺点。根据项目需求,可以选择适合的架构:

  • 适合 SPA:需要高交互性和复杂前端逻辑的应用,例如管理后台、Web 应用等。
  • 适合传统多页面应用:需要良好 SEO 支持的应用,例如新闻网站、博客等。

21. Vue 单页应用与多页应用的区别

在 Vue.js 开发中,单页面应用(SPA)和多页面应用(MPA)是两种常见的架构模式。以下是它们的详细对比:


1. ​概念

  • SPA(单页面应用)​
    只有一个主页面,首次加载时加载所有必要的 JavaScript、CSS 等资源。所有内容都包含在主页面中,页面跳转通过切换组件实现,仅刷新局部资源。

  • MPA(多页面应用)​
    由多个独立页面组成,每个页面都需要重复加载 JavaScript、CSS 等资源。页面跳转需要整页刷新。


2. ​资源加载

  • SPA

    • 首次加载时加载所有资源,后续页面切换仅加载必要的数据。
    • 资源加载量较大,但后续交互速度快。
  • MPA

    • 每次页面跳转都需要重新加载所有资源。
    • 资源加载量较小,但页面切换速度较慢。

3. ​页面跳转

  • SPA

    • 通过路由机制动态切换组件,页面内容局部刷新。
    • 用户体验流畅,无需重新加载整个页面。
  • MPA

    • 通过链接跳转到新的页面,整页刷新。
    • 页面切换时有明显的加载延迟。

4. ​开发复杂度

  • SPA

    • 需要管理路由和组件状态,开发复杂度较高。
    • 适合需要高交互性和复杂前端逻辑的应用。
  • MPA

    • 每个页面独立开发,开发复杂度较低。
    • 适合内容型网站,如新闻、博客等。

5. ​SEO 支持

  • SPA

    • 由于页面内容通过 JavaScript 动态生成,SEO 支持较差。
    • 需要额外配置(如 SSR)来优化 SEO。
  • MPA

    • 每个页面都是独立的 HTML 文件,SEO 支持较好。
    • 适合需要良好搜索引擎排名的项目。

6. ​性能

  • SPA

    • 首次加载时间较长,但后续交互速度快。
    • 适合需要频繁交互的应用。
  • MPA

    • 每次页面跳转都需要重新加载资源,性能较差。
    • 适合内容型网站,交互较少。

对比图表

特性SPA(单页面应用)​MPA(多页面应用)​
资源加载首次加载所有资源,后续局部更新每次页面跳转都重新加载资源
页面跳转动态切换组件,局部刷新整页刷新
开发复杂度较高,需管理路由和状态较低,每个页面独立开发
SEO 支持较差,需额外配置优化较好,页面为独立 HTML 文件
性能首次加载慢,后续交互快每次跳转都重新加载,性能较差

总结

  • SPA:适合需要高交互性和复杂前端逻辑的应用,例如管理后台、Web 应用等。
  • MPA:适合内容型网站,例如新闻、博客等,需要良好的 SEO 支持。

根据项目需求,可以选择适合的架构模式。如果需要更详细的示例或代码实现,请告知!