2025前端面试题—Vue篇

好的!我将为你整理 100 道 Vue 面试题,覆盖 Vue2 和 Vue3 的核心知识点,并为每道题提供完整的代码块示例。题目将涵盖以下几个模块:


🧱 分类结构预览:

  1. Vue 基础与模板语法

  2. 响应式系统

  3. 组件系统与通信

  4. 生命周期与钩子

  5. Composition API(Vue3)

  6. 指令与条件渲染

  7. 事件处理与表单绑定

  8. 插槽与动态组件

  9. 状态管理(Vuex & Pinia)

  10. Vue Router 与路由守卫

  11. 性能优化与技巧

  12. TypeScript 与 Vue3

  13. 项目实践与部署

  14. SSR 与 Nuxt

  15. 测试、调试与工具链


我们将按模块依次输出 100 道 Vue 面试题,每题包含:

  • ✅ 面试题目

  • 🔍 解析说明

  • 📘 Vue2 示例

  • 📘 Vue3 示例


✅ 模块一:Vue 基础与模板语法(1–10)


1. Vue 中如何实现数据的双向绑定?

🔍 解析:
Vue2 使用 v-model 实现 value@input 的组合;Vue3 改为 modelValue + update:modelValue

📘 Vue2 示例:

<template>
  <input v-model="msg" />
</template>

<script>
export default {
  data() {
    return {
      msg: ''
    };
  }
}
</script>

📘 Vue3 示例:

<!-- 父组件 -->
<MyInput v-model="msg" />

<!-- 子组件 -->
<template>
  <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template>

<script setup>
defineProps(['modelValue']);
defineEmits(['update:modelValue']);
</script>

2. Vue 的指令有哪些?

🔍 解析:
常用指令有:

  • v-bind:绑定属性

  • v-model:双向绑定

  • v-if/v-else/v-else-if:条件渲染

  • v-for:列表渲染

  • v-on:事件绑定

  • v-show:切换显示状态

  • v-html:插入 HTML

📘 示例:

<template>
  <div v-if="isShow">Hello</div>
  <button @click="isShow = !isShow">Toggle</button>
</template>

<script>
export default {
  data() {
    return { isShow: true };
  }
}
</script>

3. v-if 和 v-show 有什么区别?

🔍 解析:

  • v-if 是真正的条件渲染(DOM 创建与销毁)

  • v-show 是 display 的切换(性能更优)

📘 示例:

<template>
  <div>
    <p v-if="visible">使用 v-if</p>
    <p v-show="visible">使用 v-show</p>
    <button @click="visible = !visible">切换</button>
  </div>
</template>

<script>
export default {
  data() {
    return { visible: true };
  }
}
</script>

4. Vue 如何绑定 HTML 属性?

🔍 解析:
使用 v-bind 或简写 :。如 :src="url":[attr]="value" 动态绑定属性名。

📘 示例:

<template>
  <img :src="imgUrl" />
</template>

<script>
export default {
  data() {
    return {
      imgUrl: 'https://example.com/logo.png'
    };
  }
}
</script>

5. v-for 的 key 为什么重要?

🔍 解析:
key 有助于 Vue 精确追踪节点,提升渲染效率,避免错误复用组件状态。

📘 示例:

<template>
  <ul>
    <li v-for="item in list" :key="item.id">{{ item.name }}</li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      list: [{ id: 1, name: 'A' }, { id: 2, name: 'B' }]
    };
  }
}
</script>

6. Vue 如何监听用户输入事件?

🔍 解析:
使用 v-on@,监听事件如 @click@input 等。

📘 示例:

<template>
  <input @input="onInput" />
</template>

<script>
export default {
  methods: {
    onInput(e) {
      console.log(e.target.value);
    }
  }
}
</script>

7. v-model 和 prop + emit 的区别?

🔍 解析:

  • v-model 是语法糖(简洁)

  • prop + emit 是底层机制,更灵活

📘 Vue3 子组件使用:

<template>
  <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template>

<script setup>
defineProps(['modelValue']);
defineEmits(['update:modelValue']);
</script>

8. Vue 模板中如何使用三元表达式?

🔍 解析:
模板插值支持 JavaScript 表达式(不能有语句)。

📘 示例:

<template>
  <p>{{ isAdmin ? '管理员' : '用户' }}</p>
</template>

<script>
export default {
  data() {
    return { isAdmin: true };
  }
}
</script>

9. Vue 中的 computed 有什么作用?

🔍 解析:

  • 计算属性,基于依赖缓存结果

  • 适合纯函数型逻辑处理

📘 示例:

<template>
  <p>总价:{{ total }}</p>
</template>

<script>
export default {
  data() {
    return { price: 100, count: 2 };
  },
  computed: {
    total() {
      return this.price * this.count;
    }
  }
}
</script>

10. Vue 中的 methods 和 computed 有什么区别?

🔍 解析:

  • computed 有缓存,适合依赖数据变化的值

  • methods 每次调用都重新计算

📘 对比示例:

<template>
  <div>
    <p>Computed: {{ doubleCount }}</p>
    <p>Method: {{ getDoubleCount() }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return { count: 5 };
  },
  computed: {
    doubleCount() {
      console.log('computed');
      return this.count * 2;
    }
  },
  methods: {
    getDoubleCount() {
      console.log('method');
      return this.count * 2;
    }
  }
}
</script>

✅ 模块二:响应式系统(11–20)


11. Vue 的响应式原理是什么?

🔍 解析:

  • Vue2 使用 Object.defineProperty() 劫持 data 属性;

  • Vue3 使用 Proxy 实现响应式系统,更强大、可嵌套、支持数组等结构。

📘 Vue2 简化示例:

let data = {};
Object.defineProperty(data, 'msg', {
  get() {
    console.log('读取 msg');
    return 'hello';
  },
  set(newVal) {
    console.log('设置 msg', newVal);
  }
});
data.msg = 'hi';

📘 Vue3 示例:

import { reactive, effect } from 'vue';

const state = reactive({ count: 0 });

effect(() => {
  console.log('count 是:', state.count);
});

state.count++; // 触发依赖收集与响应

12. Vue3 中 reactive 和 ref 的区别?

🔍 解析:

对比reactiveref
类型 对象响应式 基本类型响应式(也可包对象)
返回 响应式对象 包装对象(.value
使用场景 多属性对象 单值、布尔值、字符串等

📘 示例:

import { reactive, ref } from 'vue';

const obj = reactive({ a: 1 });
const num = ref(10);

console.log(obj.a);     // 1
console.log(num.value); // 10

13. Vue 中 watch 与 computed 的区别?

🔍 解析:

  • computed 是依赖值的衍生属性(有缓存)

  • watch 是监听副作用(执行回调)

📘 示例:

import { ref, watch, computed } from 'vue';

const count = ref(0);
const double = computed(() => count.value * 2);

watch(count, (newVal, oldVal) => {
  console.log(`count 从 ${oldVal} 变为 ${newVal}`);
});

14. Vue2 如何实现响应式数组监听?

🔍 解析:

Vue2 中重写了数组的变更方法(如 push、splice、shift、pop 等),来实现响应式,但直接用 arr[0] = val 是不会响应的。

📘 示例:

let vm = new Vue({
  data() {
    return {
      list: [1, 2, 3]
    };
  }
});
vm.list.push(4); // 可响应
vm.list[0] = 100; // 不可响应,需使用 $set

15. 如何深度监听对象变化?

🔍 解析:
使用 watchdeep: true 选项。

📘 示例:

watch(
  () => state.obj,
  (newVal) => {
    console.log('对象发生变化', newVal);
  },
  { deep: true }
);

16. 为什么 Vue2 不能监听对象新增属性?

🔍 解析:
Vue2 的响应式依赖 Object.defineProperty,只能劫持已存在属性,新增属性不会自动变成响应式。

📘 示例:

vm.obj.newKey = 123; // 无效
vm.$set(vm.obj, 'newKey', 123); // 有效

17. Vue3 是如何解决 Vue2 的响应式缺陷的?

🔍 解析:
Vue3 使用 Proxy 重构响应式系统,可代理整个对象,支持深层嵌套和属性动态添加。

📘 示例:

const state = reactive({});
state.a = 1; // 直接添加新属性也是响应式

18. ref 包装对象和 reactive 的区别?

🔍 解析:

  • ref({}) 返回的是对象的响应式包装(取值需 .value

  • reactive({}) 直接返回响应式对象

📘 示例:

const obj1 = ref({ a: 1 });
const obj2 = reactive({ a: 1 });

console.log(obj1.value.a); // ref
console.log(obj2.a);       // reactive

19. readonly 有什么作用?

🔍 解析:
readonly() 可创建只读响应式对象,适用于防止外部修改。

📘 示例:

import { reactive, readonly } from 'vue';

const state = reactive({ count: 0 });
const roState = readonly(state);

roState.count = 100; // 会提示警告

20. shallowReactive 和 shallowRef 有什么区别?

🔍 解析:

API说明
shallowReactive 只处理一层响应式
shallowRef ref,只追踪顶层 .value

📘 示例:

import { shallowReactive, shallowRef } from 'vue';

const obj = shallowReactive({ nested: { num: 1 } });
const num = shallowRef(0);

obj.nested.num = 2; // 不响应
num.value = 10;     // 响应

✅ 模块三:组件系统与通信(21–30)


21. 父组件如何向子组件传值?

🔍 解析:
使用 props 传递数据。

📘 Vue2 示例:

<!-- Parent.vue -->
<template>
  <Child :msg="parentMsg" />
</template>

<script>
import Child from './Child.vue';
export default {
  components: { Child },
  data() {
    return { parentMsg: 'hello from parent' };
  }
};
</script>
<!-- Child.vue -->
<template>
  <p>{{ msg }}</p>
</template>

<script>
export default {
  props: ['msg']
};
</script>

📘 Vue3 示例:

<!-- Child.vue -->
<script setup>
defineProps(['msg']);
</script>

<template>
  <p>{{ msg }}</p>
</template>

22. 子组件如何向父组件传值?

🔍 解析:
通过 $emit 或 Vue3 中的 defineEmits 触发自定义事件。

📘 Vue2 示例:

<!-- Child.vue -->
<template>
  <button @click="$emit('customEvent', '子组件数据')">传值</button>
</template>
<!-- Parent.vue -->
<Child @customEvent="handleChildData" />

<script>
methods: {
  handleChildData(data) {
    console.log('来自子组件的数据:', data);
  }
}
</script>

📘 Vue3 示例:

<!-- Child.vue -->
<script setup>
const emit = defineEmits(['customEvent']);
</script>

<template>
  <button @click="emit('customEvent', 'Hello from child')">传值</button>
</template>

23. 非父子组件如何通信?

🔍 解析:

  1. 使用事件总线(Vue2 常用)

  2. 使用状态管理(Vuex / Pinia)

  3. 使用 provide/inject(父链传递)

📘 事件总线(Vue2):

// bus.js
import Vue from 'vue';
export const EventBus = new Vue();
// 组件A触发
EventBus.$emit('msg', 'hello');

// 组件B监听
EventBus.$on('msg', (val) => console.log(val));

24. 如何使用 provideinject 实现通信?

🔍 解析:
适合祖孙组件通信;Vue2 支持基本用法,Vue3 更灵活。

📘 Vue3 示例:

<!-- 父组件 -->
<script setup>
import { provide } from 'vue';
provide('themeColor', 'red');
</script>
<!-- 孙组件 -->
<script setup>
import { inject } from 'vue';
const color = inject('themeColor');
</script>

<template><div :style="{ color }">文字</div></template>

25. Vue 组件的生命周期有哪些?

🔍 解析:

  • Vue2:beforeCreate → created → beforeMount → mounted → beforeUpdate → updated → beforeDestroy → destroyed

  • Vue3:组合式 API 中使用 onMounted()onUnmounted()

📘 Vue3 示例:

import { onMounted, onUnmounted } from 'vue';

onMounted(() => {
  console.log('组件挂载');
});
onUnmounted(() => {
  console.log('组件卸载');
});

26. Vue2 中的 keep-alive 有什么作用?

🔍 解析:
<keep-alive> 用于缓存组件状态,避免重复渲染,常用于 tab 页面或表单。

📘 示例:

<keep-alive>
  <component :is="currentView" />
</keep-alive>

27. v-model 在自定义组件中如何实现?

🔍 解析:

  • Vue2:通过 value prop + input 事件

  • Vue3:使用 modelValue + update:modelValue

📘 Vue3 示例:

<!-- MyInput.vue -->
<script setup>
defineProps(['modelValue']);
defineEmits(['update:modelValue']);
</script>

<template>
  <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template>

28. 如何实现具名插槽?

🔍 解析:
插槽可以具名,适用于组件结构灵活时。

📘 示例:

<!-- MyLayout.vue -->
<template>
  <header><slot name="header" /></header>
  <main><slot /></main>
  <footer><slot name="footer" /></footer>
</template>
<!-- 使用 -->
<MyLayout>
  <template #header><h1>顶部</h1></template>
  <p>中间内容</p>
  <template #footer><p>底部</p></template>
</MyLayout>

29. 动态组件是如何实现的?

🔍 解析:
通过 <component :is="componentName" /> 实现动态切换组件。

📘 示例:

<template>
  <component :is="currentComponent" />
</template>

<script>
import A from './A.vue';
import B from './B.vue';

export default {
  data() {
    return {
      currentComponent: 'A'
    };
  },
  components: { A, B }
}
</script>

30. 子组件如何访问父组件实例?

🔍 解析:

  • Vue2 可使用 this.$parent

  • Vue3 推荐使用 provide/inject

📘 Vue2 示例:

mounted() {
  console.log('父组件 msg:', this.$parent.msg);
}

⚠️ 注意:这是一种紧耦合方式,不推荐频繁使用。


✅ 模块四:生命周期与钩子(31–40)


31. Vue2 生命周期的执行顺序是什么?每个阶段做什么?

🔍 解析:

Vue2 生命周期顺序如下:

beforeCreate → created → beforeMount → mounted → beforeUpdate → updated → beforeDestroy → destroyed

📘 用途简要说明:

阶段说明
beforeCreate 实例初始化,data/props 不可访问
created 已创建实例,可访问数据、methods,适合发请求
beforeMount 模板编译前
mounted DOM 已挂载,适合操作 DOM
beforeUpdate 数据变更但 DOM 未更新
updated DOM 已完成更新
beforeDestroy 实例销毁前
destroyed 实例已销毁,事件解绑等

📘 示例代码:

export default {
  beforeCreate() {
    console.log('beforeCreate');
  },
  created() {
    console.log('created');
  },
  mounted() {
    console.log('mounted');
  },
  beforeDestroy() {
    console.log('beforeDestroy');
  },
  destroyed() {
    console.log('destroyed');
  }
};

32. Vue3 的生命周期钩子如何写?

🔍 解析:
使用 Composition API 中的 onXxx() 函数。

📘 示例:

import { onMounted, onBeforeUnmount } from 'vue';

onMounted(() => {
  console.log('组件已挂载');
});

onBeforeUnmount(() => {
  console.log('组件即将卸载');
});

33. 在 mountedcreated 中发请求有什么区别?

🔍 解析:

  • created:数据已初始化,但 DOM 未挂载 → 更快,适合数据准备

  • mounted:DOM 已挂载 → 若请求依赖 DOM,则用 mounted

📘 示例:

created() {
  axios.get('/api/list').then(res => {
    this.list = res.data;
  });
}

34. 哪些生命周期在服务端渲染(SSR)中不会执行?

🔍 解析:

在 SSR 中,beforeMountmountedupdated 等涉及 DOM 的生命周期不会被执行。


35. Vue3 中的 setup 是在什么时候执行的?

🔍 解析:

setup() 是在组件创建前执行的,是 Composition API 的入口,比 Vue2 的 created 更早,不能访问 this

📘 示例:

<script setup>
console.log('setup 执行'); // 在生命周期最开始
</script>

36. 生命周期中做 DOM 操作应该选哪个钩子?

🔍 解析:

Vue2mounted,因为此时 DOM 已插入
Vue3onMounted

📘 Vue3 示例:

onMounted(() => {
  const el = document.getElementById('myDiv');
  console.log(el.innerText);
});

37. 如何监听组件销毁?可以做什么?

🔍 解析:

使用:

  • Vue2:beforeDestroy, destroyed

  • Vue3:onBeforeUnmount, onUnmounted

📘 示例:

onBeforeUnmount(() => {
  console.log('组件将被卸载');
});

常用于:

  • 清理定时器

  • 移除事件监听器

  • 取消网络请求


38. Vue3 的 onUpdatedwatchEffect 有什么区别?

🔍 解析:

  • onUpdated:在 DOM 更新后触发

  • watchEffect:响应式副作用追踪,更早触发,适用于数据变动时执行副作用逻辑

📘 示例:

watchEffect(() => {
  console.log('数据变了,自动运行');
});

onUpdated(() => {
  console.log('DOM 更新完毕');
});

39. 生命周期中哪些适合发请求?

🔍 解析:

  • Vue2created(推荐)、mounted(如果依赖 DOM)

  • Vue3setup 中直接写或用 onMounted(推荐)


40. 如何在 Vue3 中封装通用的生命周期逻辑?

🔍 解析:

可通过 组合函数 封装生命周期逻辑,便于复用。

📘 示例:

// usePageLog.js
import { onMounted, onUnmounted } from 'vue';

export function usePageLog() {
  onMounted(() => console.log('页面打开'));
  onUnmounted(() => console.log('页面关闭'));
}
// 组件中使用
import { usePageLog } from './usePageLog';
usePageLog();

✅ 模块五:指令与模板语法(41–50)


41. Vue 的模板语法有哪些核心语法?

🔍 解析:

  • 插值语法:{{ msg }}

  • 指令语法:v-bind, v-if, v-for, v-model, v-on

  • 缩写:

    • : => v-bind:

    • @ => v-on:

📘 示例:

<template>
  <div :title="tip" v-if="visible">
    {{ msg }}
  </div>
</template>

42. v-ifv-show 有什么区别?使用场景?

🔍 解析:

特性v-ifv-show
控制方式 DOM 创建/销毁 CSS 控制 display
性能 切换频繁时性能差 切换频繁时性能优
初始渲染 不渲染隐藏部分 渲染后隐藏

📘 示例:

<p v-if="isLogin">欢迎回来</p>
<p v-show="isLogin">欢迎回来</p>

43. 如何使用 v-for 渲染列表?并说明 key 的作用。

🔍 解析:

  • v-for 用于循环渲染数组/对象

  • key 用于提升虚拟 DOM 更新效率,应避免使用索引

📘 示例:

<ul>
  <li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>

44. 如何监听用户输入?

🔍 解析:

  • 使用 v-model 实现双向绑定

  • 可搭配 @input, @change 等事件精细控制

📘 示例:

<input v-model="msg" @input="handleInput" />

45. v-bind 的用法有哪些?可以绑定什么?

🔍 解析:

  • 用于绑定 HTML 属性、组件 props、样式、class 等

  • 可单个或对象绑定

📘 示例:

<!-- 单个 -->
<img :src="imgUrl" />

<!-- 对象绑定 style -->
<div :style="{ color: textColor, fontSize: size + 'px' }"></div>

<!-- 绑定 class -->
<div :class="{ active: isActive }"></div>

46. Vue 的事件修饰符有哪些?

🔍 解析:

修饰符含义
.stop 阻止冒泡
.prevent 阻止默认行为
.once 事件只触发一次
.capture 使用捕获模式
.self 仅在自身上触发
.native 子组件绑定原生事件(Vue2)

📘 示例:

<button @click.stop.prevent="handleClick">点击</button>

47. 如何使用修饰符限制 v-model 的行为?

🔍 解析:

  • .lazy: 在 change 而非 input 时更新

  • .number: 自动将输入转为 number

  • .trim: 自动去除首尾空格

📘 示例:

<input v-model.lazy="msg" />
<input v-model.number="age" />
<input v-model.trim="username" />

48. 如何定义自定义指令?

🔍 解析:

📘 Vue2:

Vue.directive('focus', {
  inserted(el) {
    el.focus();
  }
});

📘 Vue3:

const app = createApp(App);
app.directive('focus', {
  mounted(el) {
    el.focus();
  }
});

📘 使用:

<input v-focus />

49. 如何使用模板引用(ref)访问 DOM 或组件?

🔍 解析:

  • Vue2:使用 $refs

  • Vue3:ref() + onMounted

📘 Vue2:

<input ref="input" />
this.$refs.input.focus();

📘 Vue3:

<script setup>
import { ref, onMounted } from 'vue';
const inputRef = ref(null);
onMounted(() => inputRef.value.focus());
</script>

<template>
  <input ref="inputRef" />
</template>

50. 如何使用 v-html 渲染 HTML?有哪些风险?

🔍 解析:

  • 作用:将字符串渲染为 HTML

  • 风险:可能造成 XSS 攻击,须谨慎使用

📘 示例:

<div v-html="rawHtml"></div>

⚠️ 避免直接渲染用户输入的内容,应过滤后使用。


✅ 模块六:Vue Router 与路由管理(51–60)


51. Vue Router 是什么?

🔍 解析:

Vue Router 是 Vue 官方的路由管理器,实现单页面应用(SPA)页面导航和状态管理,支持 URL 路由映射、嵌套路由、导航守卫等。


52. 如何在 Vue2 中安装并使用 Vue Router?

📘 示例:

import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from './views/Home.vue';

Vue.use(VueRouter);

const routes = [
  { path: '/', component: Home }
];

const router = new VueRouter({
  routes
});

new Vue({
  router,
  render: h => h(App)
}).$mount('#app');

53. Vue3 如何使用 Vue Router 4?

📘 示例:

import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import App from './App.vue';
import Home from './views/Home.vue';

const routes = [{ path: '/', component: Home }];

const router = createRouter({
  history: createWebHistory(),
  routes
});

const app = createApp(App);
app.use(router);
app.mount('#app');

54. 什么是动态路由?如何定义?

🔍 解析:

动态路由是带参数的路由,路径中包含变量(如 :id),用于匹配不同参数。

📘 示例:

const routes = [
  { path: '/user/:id', component: User }
];

访问 /user/123id123


55. 如何获取路由参数?

📘 Vue2:

this.$route.params.id

📘 Vue3:

import { useRoute } from 'vue-router';
const route = useRoute();
console.log(route.params.id);

56. 路由导航守卫是什么?有哪些类型?

🔍 解析:

用于控制路由访问权限,常用于鉴权。

类型:

  • 全局守卫:beforeEachafterEach

  • 路由独享守卫:beforeEnter

  • 组件内守卫:beforeRouteEnterbeforeRouteLeavebeforeRouteUpdate


57. 如何实现路由懒加载?

🔍 解析:

使用动态导入,减少首屏加载体积。

📘 示例:

const Home = () => import('./views/Home.vue');

const routes = [
  { path: '/', component: Home }
];

58. 路由如何实现嵌套?

🔍 解析:

通过子路由实现嵌套,父组件内放置 <router-view>

📘 示例:

const routes = [
  {
    path: '/parent',
    component: Parent,
    children: [
      { path: 'child', component: Child }
    ]
  }
];

59. Vue Router 如何编程式导航?

📘 示例:

// Vue2
this.$router.push('/home');

// Vue3
import { useRouter } from 'vue-router';
const router = useRouter();
router.push('/home');

60. 如何实现路由重定向?

📘 示例:

const routes = [
  { path: '/home', component: Home },
  { path: '/', redirect: '/home' }
];

✅ 模块七:状态管理 Vuex / Pinia(61–70)


61. 什么是 Vuex?它解决了什么问题?

🔍 解析:
Vuex 是 Vue 官方的状态管理库,解决多组件间共享状态复杂的问题,集中管理应用的状态,便于维护和调试。


62. Vuex 的核心概念有哪些?

  • State:存储状态

  • Getters:计算衍生状态

  • Mutations:同步修改状态

  • Actions:异步操作,提交 mutations

  • Modules:分模块管理状态


63. Vue2 中如何安装使用 Vuex?

📘 示例:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: { count: 0 },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

new Vue({
  store,
  render: h => h(App)
}).$mount('#app');

64. Vue3 中如何使用 Vuex?

📘 示例:

import { createApp } from 'vue';
import { createStore } from 'vuex';
import App from './App.vue';

const store = createStore({
  state() {
    return { count: 0 };
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

const app = createApp(App);
app.use(store);
app.mount('#app');

65. 如何使用 Vuex 的 state 和 mutations?

📘 示例:

// 访问 state
computed: {
  count() {
    return this.$store.state.count;
  }
},

// 调用 mutation
methods: {
  increment() {
    this.$store.commit('increment');
  }
}

66. Vuex 中 actions 的作用是什么?

🔍 解析:
用于封装异步逻辑,通过 commit 调用 mutations。

📘 示例:

actions: {
  asyncIncrement({ commit }) {
    setTimeout(() => {
      commit('increment');
    }, 1000);
  }
}

67. 什么是 Vuex 的 getters?

🔍 解析:
类似计算属性,用于从 state 派生数据。

📘 示例:

getters: {
  doubleCount(state) {
    return state.count * 2;
  }
}

组件内:

computed: {
  doubleCount() {
    return this.$store.getters.doubleCount;
  }
}

68. Vue3 推荐使用什么状态管理库替代 Vuex?

🔍 解析:
Pinia,被官方推荐为 Vue3 生态的状态管理库,API 更简洁,支持 TS。


69. 如何在 Vue3 中安装和使用 Pinia?

📘 示例:

import { createApp } from 'vue';
import { createPinia, defineStore } from 'pinia';
import App from './App.vue';

const pinia = createPinia();

const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: {
    increment() {
      this.count++;
    }
  }
});

const app = createApp(App);
app.use(pinia);
app.mount('#app');

组件内使用:

import { useCounterStore } from './stores/counter';

const counter = useCounterStore();
counter.increment();

70. Pinia 和 Vuex 的主要区别是什么?

特性VuexPinia
API 复杂,需分为 state/mutations/actions/getters 简洁,store 统一管理状态和方法
类型支持 较弱 优秀,支持 TS
设计理念 Flux 风格 更灵活,类似 Composition API
模块管理 通过 modules 通过多个 store

 


✅ 模块八:性能优化与工程化(71–80)


71. 什么是前端性能优化?为什么重要?

🔍 解析:
前端性能优化是提升页面加载速度、响应速度和用户体验的技术手段。提升性能能减少用户等待时间,降低跳出率。


72. Vue 应用中常见的性能瓶颈有哪些?

  • 大量不必要的组件重新渲染

  • 频繁的 DOM 操作

  • 资源(JS/CSS/图片)体积过大

  • 不合理的事件监听


73. 如何避免 Vue 组件的重复渲染?

🔍 解析:

  • 使用 v-once 静态内容只渲染一次

  • 合理使用 key 确保列表高效渲染

  • 使用计算属性代替复杂表达式

  • 使用 shouldComponentUpdate(Vue 没有此 API,但可用 watchcomputed 优化)


74. Vue 中如何使用 keep-alive

🔍 解析:
<keep-alive> 缓存组件状态,避免组件重复渲染,常用于路由组件。

📘 示例:

<keep-alive>
  <router-view />
</keep-alive>

75. 什么是懒加载?Vue 如何实现?

🔍 解析:
懒加载指按需加载资源,减少初始包体积。

📘 示例(路由懒加载):

const Home = () => import('./views/Home.vue');

76. Vue 如何减少事件监听器的性能消耗?

🔍 解析:

  • 使用事件修饰符 .once,减少事件绑定次数

  • 委托事件,避免给多个元素绑定事件

  • 使用节流(throttle)或防抖(debounce)优化频繁触发事件


77. 如何用代码分割优化 Vue 应用?

🔍 解析:
利用动态 import 使代码拆分成多个包,按需加载。


78. Vue 组件内如何避免过度 watch?

🔍 解析:
只监听必要的数据,避免监听整个对象或数组,减少无效响应。


79. 前端资源压缩和缓存策略有哪些?

  • JS/CSS 压缩混淆

  • 图片压缩

  • 合理设置 Cache-Control

  • 使用 Service Worker 缓存静态资源


80. 如何使用 Vue CLI 优化生产环境构建?

🔍 解析:

  • 配置 vue.config.js 开启 gzip

  • 配置按需加载

  • 配置打包分析工具


✅ 模块九:综合应用与实战(81–90)


81. 如何在 Vue 中实现表单验证?

🔍 解析:
可使用第三方库如 VeeValidate、 vuelidate,也可手写校验逻辑结合 watchcomputed

📘 示例(简单示范):

<template>
  <input v-model="email" @blur="validateEmail" />
  <p v-if="error">{{ error }}</p>
</template>

<script>
export default {
  data() {
    return {
      email: '',
      error: ''
    }
  },
  methods: {
    validateEmail() {
      const re = /\S+@\S+\.\S+/;
      this.error = re.test(this.email) ? '' : '邮箱格式错误';
    }
  }
}
</script>

82. Vue 中如何实现父子组件双向绑定?

🔍 解析:
使用 .sync 修饰符或自定义 v-model 实现。

📘 示例(Vue2 使用 .sync):

<!-- 父组件 -->
<child-component :value="msg" @update:value="val => msg = val" />
<!-- 子组件 -->
<template>
  <input :value="value" @input="$emit('update:value', $event.target.value)" />
</template>
<script>
export default {
  props: ['value']
}
</script>

83. 如何解决 Vue 组件通信层级深的问题?

🔍 解析:

  • 使用 Vuex 或 Pinia 进行全局状态管理

  • 使用 provide/inject 传递数据

  • 事件总线(Vue2),但不推荐


84. Vue3 Composition API 中如何组织大型项目状态?

🔍 解析:
利用 setup() 函数搭配 reactiveref,并结合 Pinia 组织状态。


85. 如何在 Vue 中实现国际化(i18n)?

🔍 解析:
使用 vue-i18n 插件,配置语言包和切换方法。

📘 示例:

import { createI18n } from 'vue-i18n';

const messages = {
  en: { welcome: 'Welcome' },
  zh: { welcome: '欢迎' }
};

const i18n = createI18n({
  locale: 'en',
  messages
});

86. Vue 如何处理表单控件的默认值?

🔍 解析:
v-model 绑定初始数据,且在 datasetup 中设置默认值。


87. Vue 组件中的 $nextTick 有什么用?

🔍 解析:
在数据更新且 DOM 更新完成后执行回调,常用于操作更新后的 DOM。

📘 示例:

this.msg = '更新';
this.$nextTick(() => {
  console.log('DOM 已更新');
});

88. Vue3 如何使用 Suspense 处理异步组件?

🔍 解析:
使用 <Suspense> 包裹异步组件,支持加载状态和错误边界。

📘 示例:

<Suspense>
  <template #default>
    <AsyncComponent />
  </template>
  <template #fallback>
    <div>加载中...</div>
  </template>
</Suspense>

89. Vue 如何实现自定义事件?

🔍 解析:
子组件通过 $emit 触发事件,父组件监听。

📘 示例:

<!-- 子组件 -->
<button @click="$emit('custom-click')">点我</button>

<!-- 父组件 -->
<child-component @custom-click="handleClick" />

90. Vue 组件生命周期有哪些?

🔍 解析:

生命周期钩子作用
beforeCreate 实例初始化,数据观测之前
created 实例创建,数据观测后
beforeMount 挂载开始前
mounted 挂载完成
beforeUpdate 数据更新前
updated 数据更新后
beforeUnmount 卸载前(Vue3)
unmounted 卸载后(Vue3)

 


✅ 模块十:Vue3 新特性(91–100)


91. Vue3 中的 Composition API 是什么?

🔍 解析:
Composition API 是 Vue3 新增的 API,提供更灵活的逻辑复用和代码组织方式,通过 setup() 函数实现组件逻辑组织。


92. Vue3 中 refreactive 的区别?

🔍 解析:

  • ref 用于基本类型,返回带 .value 的响应式引用。

  • reactive 用于对象,返回响应式代理。

📘 示例:

import { ref, reactive } from 'vue';

const count = ref(0);
const state = reactive({ count: 0 });

93. 如何在 Vue3 中使用 watch 监听响应式数据?

📘 示例:

import { ref, watch } from 'vue';

const count = ref(0);

watch(count, (newVal, oldVal) => {
  console.log(`count 从 ${oldVal} 变为 ${newVal}`);
});

94. 什么是 Vue3 的 Teleport?

🔍 解析:
Teleport 用于将组件内容传送到 DOM 的另一个位置,常用于模态框、弹窗。

📘 示例:

<Teleport to="body">
  <div class="modal">弹窗内容</div>
</Teleport>

95. Vue3 如何实现自定义指令?

📘 示例:

const app = createApp(App);

app.directive('focus', {
  mounted(el) {
    el.focus();
  }
});

96. Vue3 中的 Suspense 作用?

🔍 解析:
Suspense 用于处理异步组件加载状态,支持 fallback 和错误边界。


97. Vue3 中 emits 选项的作用?

🔍 解析:
声明组件可触发的事件,提高类型推断和代码可维护性。

📘 示例:

export default {
  emits: ['update']
}

98. Vue3 中 setup 函数的返回值有什么作用?

🔍 解析:
setup 返回的对象中属性可在模板中直接使用。


99. Vue3 中如何处理多个响应式数据依赖?

🔍 解析:
通过 computed 组合多个响应式数据。

📘 示例:

import { reactive, computed } from 'vue';

const state = reactive({ a: 1, b: 2 });

const sum = computed(() => state.a + state.b);

100. Vue3 如何使用 Provide / Inject 传递状态?

📘 示例:

// 祖先组件
import { provide } from 'vue';

setup() {
  provide('key', 'value');
}

// 子组件
import { inject } from 'vue';

setup() {
  const val = inject('key');
}

全部 100 道 Vue(含 Vue2/3)面试题及详解完成!

posted @ 2025-06-09 11:23  星米尔工作室  阅读(6400)  评论(0)    收藏  举报