Skip to content
On This Page

面试题[Vue]

1. Vue2 相关

1.1 data 属性被设计为函数形式而不是对象形式

在 Vue.js 中,data 属性被设计为函数形式而不是对象形式,主要是出于组件复用和独立性的考虑。以下是几个关键原因:

  1. 组件复用: 当 Vue 组件被复用时(例如,在列表渲染或条件渲染中多次使用相同的组件),每个组件实例都应该有自己的状态(数据)。如果 data 是一个对象,那么所有的组件实例将共享同一个对象,这会导致它们的状态相互干扰。通过将 data 定义为函数,每次创建组件实例时都会调用该函数,并返回一个新的对象实例,从而确保每个组件实例都有自己的独立状态。
  2. 独立性: 组件应该尽可能地独立和可重用。当 data 是一个函数时,每个组件实例都可以在其自己的作用域内维护自己的状态,而不会受到其他组件实例的影响。这有助于保持组件的独立性和可测试性。
  3. Vue 实例: 在 Vue 的内部实现中,每个 Vue 实例(包括组件)都有一个与之关联的响应式数据对象。当 data 是一个函数时,Vue 可以在创建实例时调用该函数来获取初始数据,并将其转换为响应式对象。这确保了当组件的数据发生变化时,视图也会相应地更新。
  4. 避免冲突: 如果多个组件使用相同的对象作为它们的 data 属性,并且这些组件被同时渲染,那么它们可能会意外地修改彼此的数据,导致不可预测的行为和潜在的错误。通过将 data 定义为函数,每个组件实例都有自己的独立数据对象,从而避免了这种潜在的冲突。

总之,将 Vue 组件的 data 属性定义为函数形式是为了确保组件的独立性和可重用性,以及避免在组件实例之间共享状态时可能出现的问题。

1.2 计算属性、方法

1.3 侦听器

1.4 生命周期钩子

Vue 的生命周期可以分为8个阶段:创建阶段、挂载阶段、更新阶段和销毁阶段,每个阶段都有对应的钩子函数。具体如下:

1.5 组件之间的传值方式

1.6 v-show 和 v-if 的区别

1.7 v-model

在 Vue 中,v-model 指令可以用于双向数据绑定。当我们在父组件中使用 v-model 绑定一个属性时,Vue 会将该属性及其更新方法自动传递给子组件。

具体来说,v-model 将父组件中的属性和更新方法分别绑定到子组件的 value 属性和 input 事件上。当子组件修改了 value 的值时,会触发 input 事件,并将新的值通过该事件传递给父组件,从而实现了双向数据绑定。

vue
<!-- FatherComponent -->
<template>
  <div>
    <ChildComponent v-model="data"></ChildComponent>
    <p>Parent Component: {{ data }}</p>
  </div>
</template>

<!-- ChildComponent -->
<template>
  <div>
    <input type="text" :value="value" @input="$emit('input', $event.target.value)">
  </div>
</template>
<script>
export default {
  props: ['value']
};
</script>

1.8 nextTick

1.9 scoped

在 Vue 的单文件组件中,scoped 属性用于将样式限定在当前组件模块中,使其仅对当前组件起作用。它是一种 CSS 模块化的技术,有助于避免样式的冲突和影响范围的扩散。

具体而言,scoped 属性会给组件的 <style> 标签添加一个特殊的属性选择器,以确保只有当前组件的元素受到样式的影响。这样,组件中定义的样式规则仅在组件的范围内生效,不会影响到其他组件或全局样式。

1.10 key

1.11 keep-alive

1.12 响应式数组有哪些限制?如何解决这些限制?

1.13 复用已经封装好的组件时,在不修改原组件的前提下,如何扩展功能

在Vue中,可以通过使用混入(Mixin)来扩展已封装好的组件的功能,而无需修改原组件的代码。混入是一种可重用的Vue组件选项对象,可以包含组件的各种选项,如数据、计算属性、方法等。

通过混入,你可以在不修改原组件的情况下,重复使用相同的功能扩展逻辑,并在不同的组件中进行组合和定制化。但要注意,混入可能会引起命名冲突或逻辑复杂性,因此请谨慎使用,并确保正确处理混入的数据和方法与原组件之间的交互关系。

javascript
// 1. 创建一个混入对象,其中包含要扩展的功能:
// mixin.js
const myMixin = {
  data() {
    return {
      additionalData: 'This is additional data',
    };
  },
  methods: {
    additionalMethod() {
      console.log('This is an additional method');
    },
  },
};
export default myMixin;
vue
// 2. 在需要扩展功能的组件中导入并使用混入对象:
// MyComponent.vue
<template>
  <!-- Original component template -->
</template>

<script>
import myMixin from './mixin.js';

export default {
  mixins: [myMixin],
  // 原组件的选项继续定义...
};
</script>

2. Vue3 相关

2.1 Teleport

2.2 Suspense

2.3 Fragment

2.4 Vue3 中的动画系统有哪些改进

2.5 ref 和 reactive 的区别

3. Vue 拓展知识

3.1 Vue3 和 Vue2 的区别

  1. 性能提升
    • Vue3:通过改进虚拟 DOM 的算法和底层架构,实现了更快的渲染速度和更低的内存使用率。具体来说,Vue3 的打包大小减少了约41%,初次渲染速度提升了约55%,更新速度快了约133%,内存使用减少了约54%。
    • Diff 算法优化、静态标记提升、事件监听缓存、SSR 优化。
  2. 响应式系统
    • Vue3:使用了基于 Proxy 的响应式系统,可以监听对象的整个属性,包括新增和删除的属性。同时,Vue3 的响应式系统还可以检测数组内部数据的变化。Proxy 可以提供更加细粒度和高效的变化侦测,这使得 Vue 3 在处理响应式数据时更快且更可靠。
    • Vue2:使用的是基于 Object.defineProperty 的响应式系统,只能监听某个属性的变化,对于数组内部数据的变化需要特殊处理。
  3. API 与代码组织
    • Vue3:引入了Composition API,允许开发者使用函数来组织组件逻辑,使得代码更加简洁和可复用。所有 API 都是 import 引入的,对 Tree- shaking 很友好。此外,Vue3 还支持 TypeScript,提供了更好的类型检查和错误提示。
    • Vue2:使用的是 Options API,将组件的不同部分(如 data、computed、methods 等)分散在选项中,可能导致代码逻辑不够清晰。Vue2 对 TypeScript 的支持也相对较弱。
  4. 生命周期钩子
    • Vue3:生命周期钩子函数有所变化,例如 beforeCreatecreatedsetup() 替代,而 beforeMountmounted 等钩子函数前需要加上 on 前缀(如 onMounted)。此外,Vue3 还增加了 onRenderTrackedonRenderTriggered 等新的生命周期钩子。
    • Vue2:生命周期钩子函数包括 beforeCreatecreatedbeforeMountmounted 等,与 Vue3 有所不同。
  5. 其他特性与变化
    • 新的组件:Fragment、Teleport、Suspense。Fragment: Vue 3 组件不再要求有一个唯一的根节点,清除了很多无用的占位 div。Teleport: 允许组件渲染在别的元素内,主要开发弹窗组件的时候特别有用。Suspense: 异步组件,更方便开发有异步请求的组件。
    • 自定义渲染器:Vue 3 利用拆包,使用最近流行的 monorepo 管理方式,响应式、编译和运行时全部独立。

3.2 双向绑定和响应式的关系

双向绑定和响应式是相关但不完全相同的概念。

  • 响应式 (Reactivity): 指的是数据的变化能够自动地触发相关依赖的更新,从而保持视图和数据的同步。在 Vue.js 中,响应式系统负责追踪数据的变化,并在数据变化时更新相关的视图,使得视图能够反映出最新的数据状态。响应式系统可以通过监听数据的变化来实现,例如使用 Object.defineProperty() 或者 Proxy。【通过 数据劫持发布订阅模式 实现】
  • 双向绑定 (Two-way Binding): 是一种机制(是一种使视图和模型之间保持同步的机制),使得视图和模型之间的变化能够相互影响。当模型数据发生变化时,视图会自动更新以反映这些变化;同时,当视图中的表单元素值发生变化时,模型数据也会自动更新。在 Vue.js 中,双向绑定是通过在模板中使用 v-model 指令来实现的,它能够将表单元素和数据模型之间建立双向关联。

虽然双向绑定通常依赖于响应式系统来实现,但它们并不是完全相同的概念。响应式系统可以单独存在,用于追踪数据的变化并更新相关的视图,而双向绑定则是一种特定的应用场景,旨在实现视图和模型之间的双向同步。

3.3 Composition API 和 Options API 的区别

3.4 Proxy 和 Object.defineProperty 的区别

3.5 Vue 中使用了哪几种设计模式

3.6 Vue 中的性能优化有哪些常见的技巧

  • 使用 v-if 和 v-for 时注意避免不必要的渲染。
  • 合理使用 computed 属性和 watch 监听器。
  • 使用 keep-alive 组件缓存组件状态。
  • 使用异步组件进行按需加载。
  • 避免在模板中使用复杂的表达式。
  • 使用 key 属性管理组件和元素的复用。
  • 合理使用懒加载和分割代码。。。

4. 虚拟 DOM

5. Diff 算法

Vue2

Vue3

6. 响应式原理

Vue2

Vue3

7. 编译原理