一、Vue2 & Vue3 基础与原理
1. Vue2 和 Vue3 的响应式原理有何区别?
答案:
- Vue2:使用
Object.defineProperty劫持对象属性,仅支持对象属性的响应式,无法监听数组索引或对象属性的新增/删除。 - Vue3:采用
Proxy替代Object.defineProperty,支持对整个对象/数组的监听,解决了 Vue2 的局限性(如数组索引变化、新增属性)。
纵向延伸:
- 性能优化:
Proxy更高效,减少不必要的依赖追踪。 - 应用场景:Vue3 更适合大型项目的数据响应式需求。
更深层次问题:
- 如何手动实现一个简化版的
Proxy响应式系统? - Vue3 中如何监听
ref的变化?
2. v-if 和 v-show 的区别是什么?
答案:
v-if:条件为假时销毁元素,适合静态条件切换。v-show:通过display: none控制可见性,适合频繁切换的动态条件。
纵向延伸:
- 性能影响:
v-show更高效,但隐藏内容仍占用内存。 - SEO 优化:
v-if可避免隐藏内容被搜索引擎抓取。
更深层次问题:
- 如何结合
v-show实现动态组件切换? v-if与v-show在 Vue3 中的性能差异?
3. Vue3 的 Composition API 与 Options API 的区别?
答案:
- Composition API:通过
setup()函数组织逻辑,支持逻辑复用和更灵活的代码结构。 - Options API:将逻辑分散在生命周期钩子中,适合小型项目。
纵向延伸:
- TypeScript 支持:Composition API 对 TypeScript 的类型推导更友好。
- 代码组织:Composition API 更适合大型项目逻辑解耦。
更深层次问题:
- 如何在
setup中访问this? - 如何在 Options API 中使用自定义 Hook?
二、Vue Router 路由管理
4. Vue Router 的两种路由模式有何区别?
答案:
hash模式:URL 中包含#,兼容低版本浏览器,无需后端配置。history模式:URL 看似普通路径,需后端配置index.html作为入口。
纵向延伸:
- SEO 优化:
history模式更友好,但需确保后端支持。 - 应用场景:企业级项目常用
history模式。
更深层次问题:
- 如何实现动态路由参数?
abstract模式的适用场景?
5. 路由导航守卫有哪些类型?执行顺序是怎样的?
答案:
- 全局守卫:
beforeEach、beforeResolve、afterEach。 - 路由独享守卫:
beforeEnter。 - 组件内守卫:
beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。
纵向延伸:
-
权限控制:通过
beforeEach检查用户登录状态。 -
执行顺序:
beforeRouteLeave -> beforeEach -> beforeEnter -> beforeRouteUpdate -> beforeResolve -> afterEach
更深层次问题:
- 如何实现路由懒加载?
beforeRouteEnter中如何访问组件实例?
6. 如何实现路由的动态加载?
答案:
const Home = () => import('@/views/Home.vue');
const routes = [
{ path: '/home', component: Home }
];
纵向延伸:
- 性能优化:结合
webpack的代码分割,减少首屏加载时间。 - 应用场景:大型单页应用(SPA)。
更深层次问题:
- 如何实现按需加载?
- 动态路由与静态路由的性能对比?
三、Pinia 状态管理
7. Pinia 与 Vuex 的核心区别是什么?
答案:
| 特性 | Pinia | Vuex |
|---|---|---|
| 语法风格 | 基于 setup(),支持 Composition API | 传统 mutations/actions |
| 模块化 | 自动支持模块化 | 需手动配置 namespaced |
| TypeScript | 原生支持 | 需手动定义类型 |
纵向延伸:
- 开发体验:Pinia 简化了状态管理逻辑,减少冗余代码。
- 官方推荐:Vue3 官方推荐 Pinia 作为首选状态管理方案。
更深层次问题:
- 如何实现 Pinia 的持久化存储?
- Pinia 与
reactive的性能对比?
8. Pinia 中如何定义和修改状态?
答案:
// 定义
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() { this.count++; }
}
});
// 使用
const counter = useCounterStore();
counter.increment();
纵向延伸:
- 直接修改:可通过
store.count++直接修改状态,无需mutations。 - 性能优化:避免频繁修改状态,减少不必要的渲染。
更深层次问题:
- 如何实现异步操作?
- Pinia 的
watch与 Vue 的watch有何不同?
9. Pinia 如何实现模块化?
答案:
Pinia 默认支持模块化,通过 defineStore 分割不同功能模块:
// userStore.js
export const useUserStore = defineStore('user', {
state: () => ({ name: 'John' })
});
纵向延伸:
- 命名规范:建议按业务划分模块(如
useAuthStore)。 - 组合使用:多个模块可组合使用,避免全局污染。
更深层次问题:
- 如何实现模块间通信?
- Pinia 模块与 Vue 组件的关联?
四、Axios 异步请求
10. Axios 的拦截器如何使用?
答案:
-
请求拦截:
axios.interceptors.request.use(config => { config.headers.Authorization = 'Bearer token'; return config; }); -
响应拦截:
axios.interceptors.response.use(res => res.data, err => { if (err.response.status === 401) logout(); return Promise.reject(err); });
纵向延伸:
- 应用场景:添加认证头、错误统一处理。
- 性能优化:避免重复请求,减少服务器压力。
更深层次问题:
- 如何取消请求?
- Axios 与 Fetch API 的性能对比?
11. Axios 的 async/await 与 Promise 的区别?
答案:
async/await:语法更简洁,适合多层嵌套请求。Promise:链式调用,适合简单异步操作。
纵向延伸:
- 错误处理:
try/catch捕获async/await错误,catch处理Promise错误。 - 应用场景:复杂业务逻辑推荐
async/await。
更深层次问题:
- 如何实现请求重试?
- Axios 与 Fetch 的兼容性差异?
12. 如何防止重复请求?
答案:
-
拦截器取消请求:
const CancelToken = axios.CancelToken; let cancel; axios.get('/api/data', { cancelToken: new CancelToken(c => cancel = c) }); // 取消请求 cancel('Operation canceled');
纵向延伸:
- 应用场景:搜索输入框的防抖请求。
- 性能优化:减少无效请求,提升用户体验。
更深层次问题:
- 如何实现全局请求拦截?
- Axios 与 Vue 的响应式结合?
五、综合应用与场景问题
13. 如何实现 Vue3 的组件懒加载?
答案:
const LazyComponent = defineAsyncComponent(() => import('@/components/Lazy.vue'));
纵向延伸:
- 性能优化:按需加载组件,减少首屏加载时间。
- 应用场景:大型项目或低带宽环境。
更深层次问题:
- 如何结合 Vue Router 实现路由懒加载?
- 懒加载与异步组件的生命周期?
14. Vue3 中如何实现组件通信?
答案:
- Props/Events:父子组件通信。
- VModel:双向绑定。
- Provide/Inject:跨层级通信。
- Pinia:全局状态共享。
纵向延伸:
- 最佳实践:小型项目用
props/events,大型项目用 Pinia。 - 性能影响:避免过度使用
provide/inject导致依赖混乱。
更深层次问题:
- 如何实现跨组件事件总线?
- Vue3 中
eventBus的替代方案?
15. Vue3 的 keep-alive 如何工作?
答案:
-
缓存组件:
<keep-alive> <component :is="currentComponent" /> </keep-alive> -
生命周期钩子:
activated/deactivated。
纵向延伸:
- 应用场景:表单草稿保存、动态组件切换。
- 性能优化:避免缓存过多组件,占用内存。
更深层次问题:
- 如何动态控制缓存?
keep-alive与v-show的性能对比?
六、性能优化与高级特性
16. Vue3 的 reactive 与 ref 有何区别?
答案:
reactive:用于对象/数组的响应式,返回代理对象。ref:用于基本类型的响应式,返回包含value的对象。
纵向延伸:
- 应用场景:对象用
reactive,数字/字符串用ref。 - 性能优化:避免过度使用
reactive,减少代理开销。
更深层次问题:
- 如何实现嵌套
reactive? shallowReactive的用途?
17. Vue3 的 watchEffect 与 watch 的区别?
答案:
watchEffect:自动追踪依赖,立即执行并响应变化。watch:手动指定依赖,适合精确控制。
纵向延伸:
- 性能影响:
watchEffect可能触发多余执行,需谨慎使用。 - 应用场景:复杂依赖用
watchEffect,简单监听用watch。
更深层次问题:
- 如何停止
watchEffect? watch与computed的性能对比?
18. Vue3 的 Suspense 组件如何使用?
答案:
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
纵向延伸:
- 应用场景:异步组件加载时显示加载状态。
- 性能优化:减少白屏时间,提升用户体验。
更深层次问题:
- 如何实现多层
Suspense? Suspense与async/await的结合?
七、Vue Router 高级用法
19. 如何实现路由的动态参数传递?
答案:
// 定义动态路由
{ path: '/user/:id', component: User }
// 传递参数
router.push({ path: '/user/123' });
// 获取参数
const userId = $route.params.id;
纵向延伸:
- 正则匹配:通过
path: '/user/:id(\d+)'限制参数格式。 - 应用场景:详情页、编辑页。
更深层次问题:
- 如何实现参数变化的监听?
- 动态路由与静态路由的性能差异?
20. Vue Router 的 scrollBehavior 如何工作?
答案:
const router = new VueRouter({
scrollBehavior(to, from, savedPosition) {
if (savedPosition) return savedPosition;
return { x: 0, y: 0 };
}
});
纵向延伸:
- 应用场景:页面跳转后滚动到顶部。
- 兼容性:仅支持
history模式。
更深层次问题:
- 如何实现平滑滚动?
scrollBehavior与window.scrollTo的对比?
21. Vue Router 的 beforeRouteEnter 如何获取组件实例?
答案:
beforeRouteEnter(to, from, next) {
next(vm => {
vm.fetchData(); // 访问组件实例
});
}
纵向延伸:
- 生命周期限制:
beforeRouteEnter中无法直接访问this。 - 应用场景:数据预加载。
更深层次问题:
- 如何在
beforeRouteLeave中阻止导航? next(false)的使用场景?
八、Pinia 与 Vue3 深度整合
22. Pinia 如何与 Vue3 的 setup 结合使用?
答案:
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({ name: 'John' }),
actions: {
updateName(newName) { this.name = newName; }
}
});
纵向延伸:
- 响应式集成:Pinia 的
state自动响应式,无需额外处理。 - 开发体验:Composition API 风格代码更易维护。
更深层次问题:
- 如何实现 Pinia 的模块化?
- Pinia 与
reactive的性能对比?
23. Pinia 如何实现异步操作?
答案:
actions: {
async fetchUser(id) {
const response = await axios.get(`/api/user/${id}`);
this.user = response.data;
}
}
纵向延伸:
- 错误处理:使用
try/catch捕获异常。 - 应用场景:数据拉取、表单提交。
更深层次问题:
- 如何实现请求重试?
- Pinia 与 Axios 的拦截器结合?
24. Pinia 的 watch 与 Vue 的 watch 有何不同?
答案:
- Pinia 的
watch:监视store中的状态变化。 - Vue 的
watch:监视组件中的响应式数据。
纵向延伸:
- 性能影响:Pinia 的
watch更适合全局状态监控。 - 应用场景:数据变化时触发副作用。
更深层次问题:
- 如何实现深度监听?
- Pinia 的
watch与computed的对比?
九、Axios 与 Vue3 结合实践
25. 如何在 Vue3 中封装 Axios 请求?
答案:
import axios from 'axios';
const apiClient = axios.create({
baseURL: '/api',
timeout: 5000
});
export default {
getUser(id) {
return apiClient.get(`/user/${id}`);
}
};
纵向延伸:
- 模块化:按业务划分 API 接口(如
userApi.js)。 - 错误处理:统一拦截错误并提示用户。
更深层次问题:
- 如何实现接口权限校验?
- Axios 与 Vue 的响应式结合?
26. Axios 的 CancelToken 如何取消请求?
答案:
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/api/data', {
cancelToken: new CancelToken(c => cancel = c)
});
// 取消请求
cancel('Operation canceled');
纵向延伸:
- 应用场景:搜索输入框的防抖请求。
- 性能优化:减少无效请求,提升用户体验。
更深层次问题:
- 如何实现全局请求拦截?
- Axios 与 Fetch API 的兼容性差异?
27. 如何实现 Axios 的请求重试?
答案:
axios.interceptors.response.use(res => res, err => {
const config = err.config;
if (!config || !config.retry) return Promise.reject(err);
config.retryCount = config.retryCount || 0;
if (config.retryCount >= config.retry) return Promise.reject(err);
config.retryCount++;
return new Promise(resolve => setTimeout(() => resolve(axios(config)), 1000));
});
纵向延伸:
- 应用场景:网络不稳定时自动重试。
- 性能优化:避免无限重试,设置最大重试次数。
更深层次问题:
- 如何实现指数退避算法?
- Axios 与 Vue 的响应式结合?
十、Vue3 与 Pinia 的性能优化
28. Vue3 的 shallowReactive 和 shallowRef 有何用途?
答案:
shallowReactive:仅响应式第一层属性,适合大型对象。shallowRef:仅响应式value,适合引用类型。
纵向延伸:
- 性能优化:减少深层响应式开销,提升渲染效率。
- 应用场景:大型数据集合或第三方库对象。
更深层次问题:
- 如何实现深层响应式?
shallowReactive与reactive的性能对比?
29. Pinia 如何实现状态持久化?
答案:
import { defineStore } from 'pinia';
import { useLocalStorage } from '@vueuse/core';
export const useUserStore = defineStore('user', {
state: () => ({
name: useLocalStorage('user.name', 'John')
})
});
纵向延伸:
- 第三方库:结合
localStorage或IndexedDB。 - 应用场景:用户偏好存储。
更深层次问题:
- 如何加密存储数据?
- Pinia 与 Vue 的响应式结合?
30. Vue3 的 customRef 如何自定义响应式?
答案:
function debounceRef(value, delay) {
let timer;
return customRef((track, trigger) => ({
get() {
track();
return value;
},
set(newValue) {
clearTimeout(timer);
timer = setTimeout(() => {
value = newValue;
trigger();
}, delay);
}
}));
}
纵向延伸:
- 应用场景:搜索输入框的防抖。
- 性能优化:减少不必要的更新。
更深层次问题:
- 如何实现节流?
customRef与watch的对比?
十一、Vue Router 与 Pinia 的结合
31. 如何在 Vue Router 中使用 Pinia 状态?
答案:
// 在组件中
import { useUserStore } from '@/stores/user';
export default {
setup() {
const userStore = useUserStore();
return { userStore };
}
};
纵向延伸:
- 权限控制:结合
beforeEach检查用户登录状态。 - 应用场景:动态路由权限管理。
更深层次问题:
- 如何实现路由懒加载?
- Pinia 与 Vue Router 的生命周期钩子结合?
32. Vue Router 如何实现动态路由权限管理?
答案:
router.beforeEach(async (to, from, next) => {
const userStore = useUserStore();
if (to.meta.requiresAuth && !userStore.isLoggedIn) {
next('/login');
} else {
next();
}
});
纵向延伸:
- 动态路由:根据用户角色动态加载路由。
- 应用场景:企业级后台管理系统。
更深层次问题:
- 如何实现路由缓存?
- 动态路由与静态路由的性能对比?
33. 如何在 Pinia 中存储和读取 Vue Router 的状态?
答案:
// 存储
const router = useRouter();
piniaStore.route = router.currentRoute.value;
// 读取
const currentRoute = piniaStore.route;
纵向延伸:
- 应用场景:跨组件共享路由信息。
- 性能优化:避免频繁访问
currentRoute。
更深层次问题:
- 如何实现路由信息持久化?
- Pinia 与 Vue Router 的生命周期钩子结合?
十二、Vue3 与 Axios 的高级用法
34. 如何在 Vue3 中实现 Axios 的全局错误处理?
答案:
axios.interceptors.response.use(
res => res,
err => {
if (err.response?.status === 401) logout();
return Promise.reject(err);
}
);
纵向延伸:
- 应用场景:统一错误提示和重定向。
- 性能优化:避免重复错误处理逻辑。
更深层次问题:
- 如何实现错误日志记录?
- Axios 与 Vue 的响应式结合?
35. Axios 的 transformRequest 和 transformResponse 有何用途?
答案:
transformRequest:修改请求数据(如 JSON 转换)。transformResponse:修改响应数据(如错误码处理)。
纵向延伸:
- 应用场景:统一数据格式转换。
- 性能优化:减少业务代码中的数据处理逻辑。
更深层次问题:
- 如何实现数据脱敏?
- Axios 与 Vue 的响应式结合?
36. 如何在 Vue3 中实现 Axios 的并发请求?
答案:
const [user, posts] = await Promise.all([
axios.get('/api/user'),
axios.get('/api/posts')
]);
纵向延伸:
- 应用场景:同时获取多个资源。
- 性能优化:减少请求次数,提升加载速度。
更深层次问题:
- 如何处理部分失败?
- Axios 与 Vue 的响应式结合?
十三、Vue3 与 Pinia 的深度整合
37. Pinia 如何实现模块间的通信?
答案:
// 在 storeA.js 中
export const useStoreA = defineStore('a', {
actions: {
updateStoreB() {
const storeB = useStoreB();
storeB.updateValue();
}
}
});
纵向延伸:
- 应用场景:跨模块状态共享。
- 性能优化:避免过度依赖,保持模块独立。
更深层次问题:
- 如何实现模块间事件总线?
- Pinia 与 Vue 的响应式结合?
38. Pinia 的 storeToRefs 有何作用?
答案:
-
作用:解构
store的state时保持响应式。const { count } = storeToRefs(useCounterStore());
纵向延伸:
- 应用场景:避免
ref丢失响应式。 - 性能优化:减少不必要的解构。
更深层次问题:
- 如何实现嵌套
storeToRefs? storeToRefs与reactive的对比?
39. Pinia 如何实现异步初始化?
答案:
export const useUserStore = defineStore('user', {
state: () => ({ user: null }),
actions: {
async init() {
this.user = await fetchUser();
}
}
});
纵向延伸:
- 应用场景:用户登录后初始化数据。
- 性能优化:避免阻塞首屏渲染。
更深层次问题:
- 如何实现自动初始化?
- Pinia 与 Vue Router 的生命周期钩子结合?
十四、Vue3 与 Vue Router 的性能优化
40. Vue3 的 v-memo 指令如何使用?
答案:
<div v-memo="[count]"> {{ count }} </div>
纵向延伸:
- 作用:跳过不需要的子树更新,提升性能。
- 应用场景:大型列表或复杂组件。
更深层次问题:
- 如何优化
v-memo的依赖项? v-memo与v-show的性能对比?
41. Vue3 的 Fragment 是什么?
答案:
-
作用:允许组件返回多个根节点。
<template> <h1>Title</h1> <p>Content</p> </template>
纵向延伸:
- 应用场景:减少不必要的嵌套。
- 性能优化:避免额外的 DOM 节点。
更深层次问题:
- 如何实现多个根节点的条件渲染?
Fragment与v-show的性能对比?
42. Vue3 的 Teleport 如何工作?
答案:
<Teleport to="#modal">
<div class="modal">Modal Content</div>
</Teleport>
纵向延伸:
- 应用场景:模态框、全局提示。
- 性能优化:避免组件层级嵌套。
更深层次问题:
- 如何实现动态
to? Teleport与v-show的性能对比?
十五、Vue3 与 Axios 的深度整合
43. 如何在 Vue3 中实现 Axios 的全局请求头?
答案:
axios.defaults.headers.common['Authorization'] = 'Bearer token';
纵向延伸:
- 应用场景:认证请求头。
- 性能优化:避免重复设置。
更深层次问题:
- 如何动态更新请求头?
- Axios 与 Vue 的响应式结合?
44. Axios 的 transformRequest 和 transformResponse 有何用途?
答案:
transformRequest:修改请求数据(如 JSON 转换)。transformResponse:修改响应数据(如错误码处理)。
纵向延伸:
- 应用场景:统一数据格式转换。
- 性能优化:减少业务代码中的数据处理逻辑。
更深层次问题:
- 如何实现数据脱敏?
- Axios 与 Vue 的响应式结合?
45. 如何在 Vue3 中实现 Axios 的并发请求?
答案:
const [user, posts] = await Promise.all([
axios.get('/api/user'),
axios.get('/api/posts')
]);
纵向延伸:
- 应用场景:同时获取多个资源。
- 性能优化:减少请求次数,提升加载速度。
更深层次问题:
- 如何处理部分失败?
- Axios 与 Vue 的响应式结合?
十六、Vue3 与 Pinia 的性能优化
46. Pinia 的 storeToRefs 有何作用?
答案:
-
作用:解构
store的state时保持响应式。const { count } = storeToRefs(useCounterStore());
纵向延伸:
- 应用场景:避免
ref丢失响应式。 - 性能优化:减少不必要的解构。
更深层次问题:
- 如何实现嵌套
storeToRefs? storeToRefs与reactive的对比?
47. Pinia 如何实现异步初始化?
答案:
export const useUserStore = defineStore('user', {
state: () => ({ user: null }),
actions: {
async init() {
this.user = await fetchUser();
}
}
});
纵向延伸:
- 应用场景:用户登录后初始化数据。
- 性能优化:避免阻塞首屏渲染。
更深层次问题:
- 如何实现自动初始化?
- Pinia 与 Vue Router 的生命周期钩子结合?
48. Pinia 的 watch 与 Vue 的 watch 有何不同?
答案:
- Pinia 的
watch:监视store中的状态变化。 - Vue 的
watch:监视组件中的响应式数据。
纵向延伸:
- 性能影响:Pinia 的
watch更适合全局状态监控。 - 应用场景:数据变化时触发副作用。
更深层次问题:
- 如何实现深度监听?
- Pinia 的
watch与computed的对比?
十七、Vue3 与 Vue Router 的性能优化
49. Vue3 的 v-memo 指令如何使用?
答案:
<div v-memo="[count]"> {{ count }} </div>
纵向延伸:
- 作用:跳过不需要的子树更新,提升性能。
- 应用场景:大型列表或复杂组件。
更深层次问题:
- 如何优化
v-memo的依赖项? v-memo与v-show的性能对比?
50. Vue3 的 Fragment 是什么?
答案:
-
作用:允许组件返回多个根节点。
<template> <h1>Title</h1> <p>Content</p> </template>
纵向延伸:
- 应用场景:减少不必要的嵌套。
- 性能优化:避免额外的 DOM 节点。
更深层次问题:
- 如何实现多个根节点的条件渲染?
Fragment与v-show的性能对比?