Vue常见题目

1. 什么是 Vue.js?它的核心特点是什么?

Vue.js 是一个渐进式 JavaScript 框架,用于构建用户界面。它的核心特点包括:

  • 响应式数据绑定

  • 组件化开发

  • 虚拟 DOM

  • 指令系统

  • 轻量级且易于集成

  • 丰富的生态系统(Vue Router, Vuex, Vue CLI等)

2. Vue 的双向数据绑定原理是什么?

Vue 使用数据劫持结合发布者-订阅者模式实现双向绑定:

复制代码
 1.通过 Object.defineProperty() 或 Proxy 对数据对象进行劫持
 2. 在 getter 中收集依赖(Watcher)
 3. 在 setter 中通知变化,触发更新
 4. 编译器解析模板指令,初始化视图
 5. Watcher 作为桥梁,连接 Observer 和 Compile

3. Vue 2.x 和 Vue 3.x 的主要区别有哪些?

复制代码
1. 响应式系统:Vue 2 使用 Object.defineProperty,Vue 3 使用 Proxy
2. 性能:Vue 3 打包体积更小,虚拟 DOM 重写,性能更好
3. Composition API:Vue 3 引入新的代码组织方式
4. 片段支持:Vue 3 支持多根节点组件
5. Teleport 和 Suspense:Vue 3 新增的内置组件
6. TypeScript 支持:Vue 3 有更好的 TS 集成
7. 自定义渲染器 API
8. 全局 API 改为应用实例 API

4. 什么是 MVVM 模式?Vue 是如何实现 MVVM 的?

复制代码
MVVM 是 Model-View-ViewModel 的缩写:
 - Model:数据模型
 - View:UI 界面
 - ViewModel:连接 View 和 Model 的桥梁


 Vue 实现 MVVM:
 1. View:模板(template)
 2. Model:数据对象(data)
 3. ViewModel:Vue 实例,通过响应式系统和模板编译连接 View 和 Model

5. Vue 的生命周期钩子有哪些?分别在什么阶段调用?

复制代码
Vue 2.x 生命周期:

beforeCreate:实例初始化后,数据观测之前
created:实例创建完成,数据观测完成
beforeMount:挂载开始之前
mounted:实例挂载到 DOM 后
beforeUpdate:数据更新时,DOM 更新前
updated:数据更新后,DOM 更新完成
beforeDestroy:实例销毁前
destroyed:实例销毁后

Vue 3.x 对应:

复制代码
beforeCreate → 使用 setup()
created → 使用 setup()
beforeMount → onBeforeMount
mounted → onMounted
beforeUpdate → onBeforeUpdate
updated → onUpdated
beforeUnmount → onBeforeUnmount
unmounted → onUnmounted

6. Vue 组件间通信的方式有哪些?

复制代码
1. 父子组件通信:
    Props 向下传递
    自定义事件向上传递 ($emit)
    v-model / .sync 语法糖
    parent/children (不推荐)
    ref 获取组件实例

2. 兄弟组件通信:
    通过共同的父组件中转
    Event Bus
    Vuex

3. 跨层级通信:
    provide / inject
    Vuex
    全局事件总线

4. 其他:
    attrs/listeners (Vue 2)
    v-bind="$attrs" (Vue 3)
    状态管理库 (Vuex, Pinia)

7. 什么是单向数据流?为什么 Vue 要采用这种设计?

单向数据流是指:

复制代码
父组件通过 props 向子组件传递数据
子组件不能直接修改 props,只能通过事件通知父组件修改

原因:

复制代码
使数据流更易于理解和调试
防止子组件意外修改父组件状态
降低组件间耦合度
更好的维护性和可预测性

8. 动态组件是什么?如何使用?

动态组件是通过 <component> 元素和 is 特性实现的组件动态切换:

vue 复制代码
<component :is="currentComponent"></component>

使用场景:

复制代码
标签页切换
根据条件渲染不同组件
动态布局系统

注意事项:

复制代码
可以使用 <keep-alive> 缓存组件状态
切换时组件会销毁和重建

9. 异步组件是什么?如何实现?

异步组件是按需加载的组件,可以提高首屏加载速度。

Vue 2.x 实现:

javascript 复制代码
components: {
  AsyncComponent: () => import('./AsyncComponent.vue')
}

Vue 3.x 新增 defineAsyncComponent:

javascript 复制代码
import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() => 
  import('./components/AsyncComponent.vue')
)

高级配置:

javascript 复制代码
const AsyncComp = defineAsyncComponent({
  loader: () => import('./Foo.vue'),
  loadingComponent: LoadingComponent,
  errorComponent: ErrorComponent,
  delay: 200,
  timeout: 3000
})

10. 什么是函数式组件?有什么特点?

函数式组件是无状态、无实例的组件,渲染开销小。

特点:

复制代码
没有响应式数据
没有实例(this)
只接受 props
无生命周期钩子
渲染性能高

Vue 2.x 声明:

javascript 复制代码
Vue.component('functional-comp', {
  functional: true,
  render(h, context) {
    // ...
  }
})

Vue 3.x 声明:

javascript 复制代码
import { h } from 'vue'
const FunctionalComp = (props, context) => {
  return h('div', props.msg)
}

11. v-if 和 v-show 的区别是什么?

复制代码
v-if:条件渲染,元素不存在于 DOM 中,切换时销毁/重建组件
v-show:条件显示,元素始终存在于 DOM 中,只是切换 display 属性

使用场景:

复制代码
v-if:切换频率低,条件不太可能改变
v-show:频繁切换,初始渲染成本高

性能考虑:

复制代码
v-if 有更高的切换开销
v-show 有更高的初始渲染开销

12. v-for 指令的 key 属性有什么作用?

key 的作用:

复制代码
帮助 Vue 识别节点身份,高效更新虚拟 DOM
避免就地复用元素
维护组件状态和子组件状态

最佳实践:

复制代码
使用唯一标识作为 key
避免使用索引作为 key(当列表顺序变化时会有问题)
在 v-for 中总是提供 key

13. v-model 的原理是什么?如何自定义 v-model?

​​答案​​:

v-model 是语法糖,默认相当于:

vue 复制代码
<input :value="value" @input="value = $event.target.value" />

自定义组件 v-model (Vue 2.x):

javascript 复制代码
model: {
  prop: 'checked',
  event: 'change'
},
props: {
  checked: Boolean
}

Vue 3.x 支持多个 v-model:

vue 复制代码
<ChildComponent v-model:title="title" v-model:content="content" />

14. Vue 有哪些内置指令?各自的作用是什么?

​​答案​​:

常用内置指令:

复制代码
v-text:更新元素的 textContent
v-html:更新元素的 innerHTML
v-show:条件显示
v-if/v-else-if/v-else:条件渲染
v-for:列表渲染
v-on (@):绑定事件
v-bind (:):绑定属性
v-model:双向绑定
v-slot (#):插槽
v-pre:跳过编译
v-once:只渲染一次
v-memo:记忆渲染 (Vue 3.2+)
v-cloak:防止闪现

15. 自定义指令是什么?如何实现?

​​答案​​:

自定义指令用于对普通 DOM 元素进行底层操作。

注册全局指令:

javascript 复制代码
// Vue 2
Vue.directive('focus', {
  inserted(el) {
    el.focus()
  }
})

// Vue 3
app.directive('focus', {
  mounted(el) {
    el.focus()
  }
})

注册局部指令:

javascript 复制代码
directives: {
  focus: {
    mounted(el) {
      el.focus()
    }
  }
}

钩子函数 (Vue 2 → Vue 3):

复制代码
bind → beforeMount
inserted → mounted
update → 移除,改用 updated
componentUpdated → updated
unbind → unmounted

16. Vue 2.x 的响应式原理是什么?有什么缺陷?

​​答案​​:

原理:

复制代码
使用 Object.defineProperty 劫持对象属性
在 getter 中收集依赖
在 setter 中通知更新
每个组件实例对应一个 Watcher 实例

缺陷:

复制代码
无法检测对象属性的添加或删除(需要 Vue.set/Vue.delete)
无法检测数组索引和长度的变化
对 ES6+ 的 Map、Set 等不支持
初始化时递归遍历所有属性,性能有影响

17. Vue 3.x 的响应式系统有什么改进?

​​答案​​:

改进:

复制代码
使用 Proxy 代替 Object.defineProperty
    可以检测属性添加/删除
    支持 Map、Set 等数据结构
性能优化:
    惰性响应式(按需响应)
    更好的缓存机制
更精确的变更检测
支持嵌套对象的自动解包
独立的响应式模块(可单独使用)

18. Vue.set/Vue.delete 的作用是什么?Vue 3 中还需要吗?

​​答案​​:

Vue 2.x 中:

复制代码
Vue.set:向响应式对象添加新属性并触发视图更新
Vue.delete:删除属性并触发视图更新

Vue 3.x 中:

复制代码
不再需要,因为 Proxy 可以检测到属性的添加和删除
但仍保留了 set 和 delete 的 API 用于兼容

19. 什么是响应式数据的副作用函数?Vue 中如何收集依赖?

​​答案​​:

副作用函数是指会对外部产生影响的函数,如修改 DOM、发送请求等。

Vue 收集依赖的过程:

复制代码
在组件渲染时,会执行 render 函数访问响应式数据
触发数据的 getter,将当前 Watcher(副作用函数)添加到依赖中
数据变化时,触发 setter,通知所有依赖的 Watcher 更新
Watcher 执行更新函数,重新渲染或执行副作用

20. computed 和 watch 的区别是什么?

​​答案​​:

computed:

复制代码
计算属性,基于依赖缓存
必须有返回值
适合派生状态
同步操作

watch:

复制代码
观察特定数据变化
无返回值
适合执行异步或复杂操作
可以观察多个数据源

使用场景:

复制代码
computed:模板中的复杂表达式、数据格式化
watch:数据变化时需要执行异步操作或复杂逻辑

虚拟 DOM 和渲染

21. 什么是虚拟 DOM?它的优点是什么?

​​答案​​:

虚拟 DOM 是真实 DOM 的轻量级 JavaScript 表示。

优点:

复制代码
减少直接操作 DOM 的性能开销
提供跨平台能力(如 SSR、Native 渲染)
高效的差异比较算法(diff)
批量更新 DOM
开发体验更接近声明式编程

工作原理:

复制代码
用 JavaScript 对象表示 DOM 结构
状态变化时生成新的虚拟 DOM
比较新旧虚拟 DOM (diff)
将差异应用到真实 DOM (patch)

22. Vue 的 diff 算法是怎样的?

​​答案​​:

Vue 的 diff 算法特点:

复制代码
同级比较,不跨级
使用 key 识别节点身份
双端比较策略(Vue 3 优化为更高效的算法)
优先处理特殊情况(如相同节点、文本节点)

优化策略:

复制代码
静态节点提升(Vue 3)
事件缓存
区块树优化(Vue 3)
更高效的 patch 标志

23. Vue 3 在虚拟 DOM 方面有哪些优化?

​​答案​​:

Vue 3 虚拟 DOM 优化:

复制代码
静态提升:将静态节点提升到渲染函数外
补丁标志:为动态节点添加标志,减少比较范围
缓存事件处理函数
区块树:将静态和动态内容分离
更高效的 diff 算法
支持片段(多根节点)
更快的挂载和更新性能

24. 什么是渲染函数?什么情况下需要使用渲染函数?

​​答案​​:

渲染函数是用于编程式创建虚拟 DOM 的函数(h 函数)。

使用场景:

复制代码
动态性很强的组件
需要更灵活的模板逻辑
高阶组件
需要 JavaScript 的完整编程能力
性能敏感场景(比模板更高效)

示例:

javascript 复制代码
render(h) {
  return h('div', { class: 'container' }, [
    h('h1', 'Title'),
    this.showSubtitle ? h('h2', 'Subtitle') : null
  ])
}

25. Vue 3 的 h 函数有什么变化?

​​答案​​:

Vue 3 中 h 函数的变化:

复制代码
需要从 vue 显式导入
更灵活的参数:
    可以省略不用的参数
    props 结构更一致
支持 VNode 的标准化
更好的 TypeScript 支持

Vue 2:

vue 复制代码
h('div', { class: 'foo', on: { click: handler } }, 'hello')

Vue 3:

vue 复制代码
h('div', { class: 'foo', onClick: handler }, 'hello')

路由系统

26. Vue Router 的导航守卫有哪些?如何使用?

​​答案​​:

导航守卫分类:

复制代码
全局守卫:
    beforeEach:前置守卫
    beforeResolve:解析守卫
    afterEach:后置钩子

路由独享守卫:
    beforeEnter

组件内守卫:
    beforeRouteEnter
    beforeRouteUpdate
    beforeRouteLeave

使用示例:

vue 复制代码
router.beforeEach((to, from, next) => {
  // 必须调用 next()
})

// 组件内
beforeRouteLeave(to, from, next) {
  // 确认离开?
  next(confirm('确认离开?'))
}

27. 路由懒加载的原理是什么?如何实现?

​​答案​​:

路由懒加载是通过动态导入实现的代码分割技术。

原理:

复制代码
使用动态 import() 语法
Webpack 将其识别为代码分割点
路由被访问时才加载对应 chunk

实现:

vue 复制代码
const routes = [
  {
    path: '/about',
    component: () => import('./views/About.vue')
  }
]

Vue 3 还可以使用 defineAsyncComponent:

vue 复制代码
const About = defineAsyncComponent(() => import('./About.vue'))

28. Vue Router 有几种路由模式?区别是什么?

​​答案​​:

两种主要模式:

复制代码
hash 模式:
    使用 URL hash (#)
    兼容性好
    不需要服务器配置
    示例:http://example.com/#/about

history 模式:

复制代码
使用 HTML5 History API
URL 更美观
需要服务器配置(避免 404)
示例:http://example.com/about

配置:

vue 复制代码
const router = createRouter({
  history: createWebHashHistory(), // hash
  history: createWebHistory(),     // history
})

29. 如何实现动态路由?有哪些应用场景?

​​答案​​:

实现方式:

复制代码
使用冒号定义动态参数:

{ path: '/user/:id', component: User }

通过 props 接收参数:

{ path: '/user/:id', component: User, props: true }

编程式导航:

复制代码
router.push('/user/' + userId)

应用场景:

复制代码
用户个人主页
商品详情页
博客文章页
任何需要根据 ID 展示不同内容的页面

30. 如何实现路由鉴权?

​​答案​​:

常见鉴权方案:

复制代码
路由元信息 + 全局守卫:
vue 复制代码
{
  path: '/admin',
  meta: { requiresAuth: true }
}

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    if (!auth.isLoggedIn()) {
      next('/login')
    } else {
      next()
    }
  } else {
    next()
  }
})

动态路由:

复制代码
根据权限动态生成路由表
使用 router.addRoute() 添加路由

组合式 API (Vue 3):

vue 复制代码
import { onBeforeRouteUpdate } from 'vue-router'

onBeforeRouteUpdate((to, from, next) => {
  // 鉴权逻辑
})

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

​​答案​​:

Vuex 核心概念:

复制代码
State:单一状态树
Getters:计算属性
Mutations:同步修改状态(commit)
Actions:异步操作(dispatch)
Modules:模块化

工作流程:

复制代码
组件 dispatch Action
Action commit Mutation
Mutation 修改 State
State 变化触发组件更新

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

​​答案​​:

Pinia 是 Vuex 的替代方案,主要区别:

复制代码
API 设计:
    Vuex 有 mutations/actions
    Pinia 只有 actions(可同步/异步)
TypeScript 支持:
    Pinia 有更好的 TS 支持
模块化:
    Vuex 需要 modules
    Pinia 自动模块化
体积:
    Pinia 更轻量
Composition API:
    Pinia 专为 Vue 3 设计
开发体验:
    Pinia 更简洁直观

33. 什么情况下应该使用 Vuex/Pinia?

​​答案​​:

使用场景:

复制代码
多个组件共享状态
多个组件需要修改同一状态
需要维护复杂的状态逻辑
需要状态的时间旅行调试
需要服务端渲染的状态保持

不适合场景:

复制代码
简单应用(可以用 provide/inject)
父子组件通信(用 props/emit)
简单全局状态(可以用 reactive)

34. 如何实现 Vuex 的模块热重载?

​​答案​​:

Vuex 模块热重载配置:

vue 复制代码
if (module.hot) {
  module.hot.accept(['./modules/moduleA'], () => {
    const newModuleA = require('./modules/moduleA').default
    store.hotUpdate({
      modules: {
        moduleA: newModuleA
      }
    })
  })
}

Pinia 自动支持热更新:

javascript 复制代码
if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useStore, import.meta.hot))
}

35. Vuex 的严格模式是什么?有什么作用?

​​答案​​:

严格模式会深度监测状态变更是否来自 mutation。

启用:

vue 复制代码
const store = new Vuex.Store({
  strict: true
})

作用:

复制代码
确保所有状态变更都经过 mutation
防止在 mutation 外修改状态
开发时更好的调试体验

注意:

复制代码
不要在生产环境使用(性能影响)
可以用发布时去除:

strict: process.env.NODE_ENV !== 'production'

组合式 API

36. 什么是组合式 API?解决了什么问题?

​​答案​​:

组合式 API 是 Vue 3 引入的新代码组织方式,包括:

复制代码
setup 函数
ref 和 reactive
生命周期钩子函数
自定义组合函数

解决的问题:

复制代码
选项式 API 在复杂组件中逻辑分散
更好的逻辑复用
更好的 TypeScript 支持
更灵活的逻辑组织
更小的函数粒度

37. setup 函数是什么?如何使用?

​​答案​​:

setup 是组合式 API 的入口函数:

复制代码
在 beforeCreate 之前调用
没有 this
接收 props 和 context 参数
返回对象暴露给模板

示例:

vue 复制代码
setup(props, context) {
  const count = ref(0)
  
  function increment() {
    count.value++
  }
  
  return {
    count,
    increment
  }
}

context 包含:

复制代码
attrs
slots
emit
expose

38. ref 和 reactive 的区别是什么?

​​答案​​:

ref:

复制代码
用于基本类型(也可以用于对象)
通过 .value 访问
模板中自动解包
更适合独立的基本值

reactive:

复制代码
用于对象
直接访问属性
解构会失去响应性
更适合复杂对象

转换:

复制代码
reactive({ count: 1 }) 类似 ref(1).value
ref(obj) 类似 reactive(obj)

39. 什么是自定义 hook?如何实现?

​​答案​​:

自定义 hook 是使用组合式 API 封装的逻辑复用函数。

实现:

vue 复制代码
// useCounter.js
import { ref } from 'vue'

export function useCounter(initialValue = 0) {
  const count = ref(initialValue)
  
  function increment() {
    count.value++
  }
  
  return {
    count,
    increment
  }
}

// 使用

vue 复制代码
import { useCounter } from './useCounter'

setup() {
  const { count, increment } = useCounter()
  return { count, increment }
}

特点:

复制代码
以 use 前缀命名
可以组合其他 hook
返回响应式状态和方法

40. watch 和 watchEffect 的区别是什么?

​​答案​​:

watch:

复制代码
明确指定侦听源
惰性执行(默认)
可以获取旧值
更精确控制触发时机

watchEffect:

复制代码
自动收集依赖
立即执行
没有旧值
适合副作用清理

示例:

javascript 复制代码
// watch
watch(count, (newVal, oldVal) => {})

// watchEffect
watchEffect(() => {
  console.log(count.value)
})

清理副作用:

javascript 复制代码
watchEffect((onInvalidate) => {
  const timer = setInterval(() => {})
  onInvalidate(() => clearInterval(timer))
})

41. 什么是 Teleport?使用场景是什么?

​​答案​​:

Teleport 是 Vue 3 内置组件,可以将内容渲染到 DOM 树的指定位置。

使用:

javascript 复制代码
<teleport to="body">
  <div class="modal">...</div>
</teleport>

场景:

复制代码
模态框
通知提示
加载条
任何需要突破父组件 DOM 层级限制的 UI

注意:

复制代码
to 可以是 CSS 选择器或 DOM 元素
内容仍保持组件上下文(如数据、指令)

42. 什么是 Suspense?如何使用?

​​答案​​:

Suspense 是 Vue 3 内置组件,用于处理异步组件加载状态。

使用:

javascript 复制代码
<Suspense>
  <template #default>
    <AsyncComponent />
  </template>
  <template #fallback>
    <div>Loading...</div>
  </template>
</Suspense>

工作原理:

复制代码
等待异步组件加载
显示 fallback 内容
加载完成后显示默认内容

注意:

复制代码
实验性功能,API 可能变化
可以配合 async setup 使用

43. 什么是渲染函数 JSX?如何在 Vue 中使用 JSX?

​​答案​​:

JSX 是 JavaScript 的语法扩展,可以在 JavaScript 中编写类似 HTML 的结构。

Vue 中使用:

复制代码
安装插件:

npm install @vue/babel-plugin-jsx -D

配置 babel:

plugins: ["@vue/babel-plugin-jsx"]

使用:

javascript 复制代码
render() {
  return <div class="container">{this.message}</div>
}

Vue 3 中:

javascript 复制代码
import { defineComponent } from 'vue'

const Component = defineComponent({
  setup() {
    return () => <div>JSX in Vue 3</div>
  }
})

44. Vue 3 的 Fragment 是什么?有什么好处?

​​答案​​:

Fragment 允许组件有多个根节点。

Vue 2 中:

复制代码
组件必须有且只有一个根元素

Vue 3 中:
... ... ...

好处:

复制代码
更灵活的模板结构
减少不必要的包装 div
更符合语义化
与 React 保持一致

45. 什么是自定义渲染器?使用场景是什么?

​​答案​​:

自定义渲染器 API 允许自定义 Vue 的渲染逻辑。

使用场景:

复制代码
非 DOM 渲染:
    小程序
    Canvas
    WebGL
    终端输出
特殊 DOM 操作需求
创建特定领域的框架

示例:

javascript 复制代码
import { createRenderer } from 'vue'

const { render, createApp } = createRenderer({
  patchProp,
  insert,
  remove,
  createElement
  // ...其他平台特定API
})

46. Vue 应用常见的性能优化手段有哪些?

​​答案​​:

常见优化:

复制代码
代码层面:
    合理使用 v-if 和 v-show
    为 v-for 设置 key
    避免同时使用 v-if 和 v-for
    使用 computed 缓存计算
    拆分复杂组件
    使用 keep-alive 缓存组件

打包层面:
    路由懒加载
    按需引入组件库
    代码分割
    压缩代码
    Tree-shaking

运行时:
    减少响应式数据量
    避免不必要的组件渲染
    防抖/节流
    虚拟滚动 (virtual scroller)

其他:
    SSR
    CDN
    服务端缓存

47. 什么是 keep-alive?如何使用?

​​答案​​:

keep-alive 是 Vue 内置组件,用于缓存不活动的组件实例。

使用:

javascript 复制代码
<keep-alive>
  <component :is="currentComponent"></component>
</keep-alive>

属性:

复制代码
include:匹配的组件名会被缓存
exclude:匹配的组件名不会被缓存
max:最多缓存组件实例数

生命周期:

复制代码
activated:组件激活时
deactivated:组件停用时

48. Vue 3 的 v-memo 是什么?如何使用?

​​答案​​:

v-memo 是 Vue 3.2+ 新增指令,用于缓存模板子树。

使用:

javascript 复制代码
<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
  {{ item.text }}
</div>

工作原理:

复制代码
依赖项不变时跳过更新
必须与 v-for 一起使用
可以显著提升性能

场景:

复制代码
大型列表
复杂条件渲染
频繁更新的 UI

49. 如何分析 Vue 应用的性能瓶颈?

​​答案​​:

分析方法:

复制代码
Vue Devtools:
    性能时间线
    组件渲染时间
    事件追踪

Chrome DevTools:
    Performance 面板
    Memory 面板
    Coverage 面板

特定工具:
    webpack-bundle-analyzer
    speed-measure-webpack-plugin
    Lighthouse

代码层面:
    检查不必要的重新渲染
    检查大型响应式对象
    检查内存泄漏

50. 如何实现虚拟滚动?有什么好处?

​​答案​​:

虚拟滚动只渲染可见区域的列表项。

实现方式:

复制代码
使用第三方库:
    vue-virtual-scroller
    vue-virtual-scroll-grid

手动实现:
    计算可见区域
    动态渲染可见项
    处理滚动事件

好处:

复制代码
减少 DOM 数量
提高渲染性能
支持超大型列表
更流畅的滚动体验

51. Vue 组件的单元测试应该测试哪些方面?

​​答案​​:

测试重点:

复制代码
渲染输出:
    是否正确渲染
    条件渲染逻辑
    列表渲染

用户交互:
    点击等事件
    表单输入
    自定义事件

状态变更:
    props 变化
    数据变化
    计算属性

生命周期:
    挂载/卸载
    更新

异步行为:
    API 调用
    定时器

52. 常用的 Vue 测试工具和库有哪些?

​​答案​​:

常用工具:

复制代码
测试运行器:
    Jest
    Vitest

测试工具:
    Vue Test Utils (官方)
    Testing Library

辅助工具:
    @vue/test-utils
    vue-jest
    jest-transform-stub

其他:
    Cypress (E2E)
    Storybook (可视化测试)

53. 如何测试 Vue 组件中的异步逻辑?

​​答案​​:

测试异步逻辑方法:

复制代码
使用 async/await:
javascript 复制代码
test('async test', async () => {
  await wrapper.find('button').trigger('click')
  expect(wrapper.text()).toContain('Updated')
})

模拟定时器:

javascript 复制代码
jest.useFakeTimers()
// 触发定时器
jest.runAllTimers()

模拟 API 调用:

javascript 复制代码
jest.mock('axios')
axios.get.mockResolvedValue({ data: {} })

flush-promises:

javascript 复制代码
await flushPromises()

54. 什么是快照测试?在 Vue 中如何实现?

​​答案​​:

快照测试是比较组件渲染结果与保存的快照是否一致。

实现:

javascript 复制代码
test('component snapshot', () => {
  const wrapper = mount(MyComponent)
  expect(wrapper.html()).toMatchSnapshot()
})

特点:

复制代码
第一次测试生成快照文件
后续测试比较结果
快照需提交到版本控制
适合静态组件

注意:

复制代码
快照不是替代品,需结合其他测试
动态内容可能导致失败
定期更新快照

55. 如何测试 Vuex store?

​​答案​​:

测试 Vuex store 方法:

复制代码
单元测试 mutations:
javascript 复制代码
test('increment mutation', () => {
  const state = { count: 0 }
  mutations.increment(state)
  expect(state.count).toBe(1)
})

测试 getters:

javascript 复制代码
test('evenOrOdd getter', () => {
  const state = { count: 1 }
  expect(getters.evenOrOdd(state)).toBe('odd')
})

测试 actions:

javascript 复制代码
test('increment action', async () => {
  const commit = jest.fn()
  await actions.increment({ commit })
  expect(commit).toHaveBeenCalledWith('increment')
})

集成测试:

javascript 复制代码
const store = createStore(options)
store.dispatch('action')
expect(store.state).toEqual(...)

56. 什么是 SSR?Vue 中如何实现 SSR?

​​答案​​:

SSR (Server-Side Rendering) 是在服务器端生成 HTML 发送到客户端。

Vue 实现方式:

复制代码
使用 Nuxt.js 框架
手动配置:
    vue-server-renderer
    Express/Koa 服务器
    Webpack 配置

优点:

复制代码
更好的 SEO
更快的内容到达时间
对低端设备更友好

缺点:

复制代码
开发复杂度高
服务器负载大
部分库需要特殊处理
  1. SSR 和 CSR 的区别是什么?

​​答案​​:

SSR (Server-Side Rendering):

复制代码
在服务器生成完整 HTML
客户端"激活"交互
首屏加载快
SEO 友好
服务器压力大

CSR (Client-Side Rendering):

复制代码
服务器返回空 HTML 和 JS
客户端渲染所有内容
首屏加载慢
SEO 不友好
服务器压力小

混合方案:

复制代码
预渲染
部分 SSR
渐进式激活
  1. Vue SSR 的性能优化手段有哪些?

​​答案​​:

SSR 优化手段:

复制代码
代码层面:
    避免单例状态
    使用 bundleRenderer
    组件级别缓存
    减少序列化数据

基础设施:
    使用 microcache
    负载均衡
    CDN
    流式渲染

其他:
    延迟加载非关键组件
    预取数据
    服务端压缩

59. 什么是 hydration?SSR 中如何处理?

​​答案​​:

hydration 是客户端 Vue 接管服务器渲染的静态 HTML 并使其交互的过程。

处理要点:

复制代码
客户端和服务器输出必须匹配

避免 hydration 不匹配警告

特殊处理客户端特有代码:

if (process.client) {
  // 只在客户端执行的代码
}

使用 <ClientOnly> 组件包装客户端特有内容

注意生命周期钩子调用时机

60. 如何处理 SSR 中的身份认证?

​​答案​​:

SSR 认证处理:

复制代码
Cookie 认证:
    服务器自动发送 cookie
    适合传统 session

Token 认证:
    服务器通过 initialState 传递 token
    客户端存储 token

双重验证:
    服务器检查 session
    客户端检查 token

注意:

复制代码
避免在服务器上使用 localStorage
处理异步用户状态
统一客户端和服务端状态

61. Vue CLI 和 Vite 的区别是什么?

​​答案​​:

Vue CLI:

复制代码
基于 Webpack
功能全面
配置复杂
启动和热更新较慢
适合复杂项目

Vite:

复制代码
基于原生 ES 模块
开发服务器极快
配置简单
生产打包使用 Rollup
适合现代浏览器项目

选择:

复制代码
新项目推荐 Vite
已有 Vue CLI 项目可逐步迁移

62. 如何优化 Vue 应用的打包体积?

​​答案​​:

优化手段:

复制代码
代码分割:
    路由懒加载
    组件异步加载

按需引入:
    组件库按需导入
    工具函数按需导入

压缩:
    JS/CSS 压缩
    图片压缩
    Gzip/Brotli

分析:
    webpack-bundle-analyzer
    移除重复依赖

其他:
    使用现代模式 (Vue CLI)
    外部化大型库

63. 如何实现 Vue 应用的预渲染?

​​答案​​:

预渲染是在构建时生成静态 HTML 文件。

实现方式:

复制代码
使用 prerender-spa-plugin:
javascript 复制代码
new PrerenderSPAPlugin({
  staticDir: path.join(__dirname, 'dist'),
  routes: ['/', '/about'],
})

使用 Vue CLI 插件:

vue add prerender-spa

使用 Vite 插件:

复制代码
import { vitePrerender } from 'vite-plugin-prerender'

适用场景:

复制代码
营销页面
内容不常变化的页面
改善 SEO

64. 如何部署 Vue 应用到不同的环境?

​​答案​​:

部署方案:

复制代码
静态部署:
    Nginx/Apache
    CDN
    GitHub Pages

服务端渲染:
    Node.js 服务器
    Docker 容器
    Serverless

现代部署:
    Vercel
    Netlify
    Cloudflare Pages

环境变量管理:

复制代码
.env 文件
Vue CLI 模式
Vite 环境变量

65. 如何处理 Vue 应用的跨域问题?

​​答案​​:

跨域解决方案:

复制代码
开发环境:
    配置 devServer.proxy (Vue CLI)

devServer: {
  proxy: {
    '/api': {
      target: 'http://localhost:3000',
      changeOrigin: true
    }
  }
}

生产环境:
    后端配置 CORS
    Nginx 反向代理
    API 网关

其他方案:
    JSONP (仅 GET)
    后端转发
    浏览器插件临时解决

进阶概念

66. 什么是高阶组件?如何实现?

​​答案​​:

高阶组件 (HOC) 是接收组件并返回新组件的函数。

实现:

javascript 复制代码
function withLoading(WrappedComponent) {
  return {
    data() {
      return { isLoading: true }
    },
    mounted() {
      setTimeout(() => {
        this.isLoading = false
      }, 1000)
    },
    render(h) {
      if (this.isLoading) {
        return h('div', 'Loading...')
      }
      return h(WrappedComponent, {
        props: this.$props
      })
    }
  }
}

使用:

javascript 复制代码
const EnhancedComponent = withLoading(MyComponent)

Vue 3 替代方案:

复制代码
组合式函数
渲染函数
插槽

67. 什么是递归组件?如何使用?

​​答案​​:

递归组件是调用自身的组件。

使用:

复制代码
通过 name 选项递归:
javascript 复制代码
<template>
  <div>
    <my-component v-if="condition" />
  </div>
</template>

<script>
export default {
  name: 'MyComponent'
}
</script>

通过组件引用递归:

javascript 复制代码
import RecursiveComponent from './RecursiveComponent.vue'
export default {
  components: {
    RecursiveComponent
  }
}

注意:

复制代码
必须有终止条件
可能影响性能
适合树形结构数据

68. 什么是作用域插槽?使用场景是什么?

​​答案​​:

作用域插槽允许子组件向插槽传递数据。

使用:

javascript 复制代码
<slot :item="item" :index="index"></slot>
javascript 复制代码
<template v-slot:default="slotProps">
  {{ slotProps.item }} - {{ slotProps.index }}
</template>

简写 (Vue 2.6+):

javascript 复制代码
<template #default="{ item, index }">
  {{ item }} - {{ index }}
</template>

场景:

复制代码
数据列表组件
表格组件
任何需要灵活内容渲染的组件

69. Vue 3 的 createApp 和 new Vue() 有什么区别?

​​答案​​:

区别:

复制代码
创建方式:
    Vue 2: new Vue({...})
    Vue 3: createApp({...})

全局 API:
    Vue 2: 全局修改 Vue 原型
    Vue 3: 应用实例作用域

配置:
    Vue 2: 全局配置
    Vue 3: 每个应用独立配置

挂载:
    Vue 2: $mount()
    Vue 3: mount()

示例:

// Vue 2

new Vue({ el: '#app' })

// Vue 3

createApp(App).mount('#app')

70. 什么是响应式丢失问题?如何解决?

​​答案​​:

响应式丢失是指解构或展开响应式对象时失去响应性。

常见场景:

复制代码
解构 props:
javascript 复制代码
const { foo } = this.props // 失去响应性

展开响应式对象:

复制代码
return { ...reactiveObj } // 失去响应性

解决方案:

复制代码
使用 toRefs:
javascript 复制代码
const { foo } = toRefs(props)

保持引用:

javascript 复制代码
return { reactiveObj }

使用 computed:

javascript 复制代码
const foo = computed(() => props.foo)

71. Vue 应用常见的错误有哪些?如何捕获?

​​答案​​:

常见错误:

复制代码
渲染错误
事件处理错误
生命周期钩子错误
异步操作错误
自定义指令错误

捕获方式:

全局错误处理:

javascript 复制代码
app.config.errorHandler = (err, vm, info) => {
  // 处理错误
}

生命周期钩子:

javascript 复制代码
errorCaptured(err, vm, info) {
  // 捕获子孙组件错误
}

异步错误:

javascript 复制代码
 window.addEventListener('unhandledrejection', e => {})
复制代码
    第三方监控:
        Sentry
        Bugsnag

### 72. 如何处理 Vue 路由中的 404 页面?

​​答案​​:
处理方式:

    通配符路由:

```javascript
{ path: '/:pathMatch(.*)*', component: NotFound }

导航守卫:

javascript 复制代码
router.beforeEach((to, from, next) => {
  if (!to.matched.length) {
    next('/404')
  } else {
    next()
  }
})

服务器配置 (history 模式):

复制代码
location / {
  try_files $uri $uri/ /index.html;
}

73. Vue 3 的 effectScope 是什么?如何使用?

​​答案​​:

effectScope 是 Vue 3.2+ 特性,用于组织和管理 effect。

使用:

javascript 复制代码
import { effectScope, reactive, watch } from 'vue'

const scope = effectScope()

scope.run(() => {
  const state = reactive({ count: 0 })
  watch(() => state.count, console.log)
  state.count++
})

scope.stop() // 停止所有 effect

场景:

复制代码
组件 setup 中管理 effect
可组合的函数中
测试时清理 effect

74. 如何处理 Vue 中的内存泄漏?

​​答案​​:

内存泄漏常见原因:

复制代码
全局变量
未清除的定时器/事件监听
未卸载的第三方库
闭包
未清理的 Vue 相关资源

解决方案:

复制代码
组件卸载时清理:
javascript 复制代码
 onUnmounted(() => {
      clearInterval(timer)
      eventBus.off('event', handler)
    })
复制代码
避免意外全局变量

使用弱引用 (WeakMap/WeakSet)

使用内存分析工具定位

75. Vue 3 的 Suspense 如何处理错误?

​​答案​​:

Suspense 错误处理:

复制代码
使用 onErrorCaptured:
javascript 复制代码
onErrorCaptured((err) => {
  error.value = err
  return false // 阻止错误继续向上传播
})

错误边界组件:

javascript 复制代码
<Suspense>
  <template #default>
    <AsyncComponent />
  </template>
  <template #fallback>
    <div v-if="error">{{ error.message }}</div>
    <div v-else>Loading...</div>
  </template>
</Suspense>

全局错误处理:

javascript 复制代码
app.config.errorHandler = (err) => {
  // 处理 Suspense 错误
}

76. Vue 3 中如何更好地使用 TypeScript?

​​答案​​:

最佳实践:

复制代码
使用 defineComponent:
javascript 复制代码
import { defineComponent } from 'vue'

export default defineComponent({
  // 类型推断
})

类型化 props:

javascript 复制代码
props: {
  message: {
    type: String as PropType<string>,
    required: true
  }
}

类型化 ref:

javascript 复制代码
const count = ref<number>(0)

类型化事件:

javascript 复制代码
const emit = defineEmits<{
  (e: 'update', value: string): void
}>()

类型化 computed:

复制代码
const double = computed<number>(() => count.value * 2)

77. 如何为 Vue 组件定义 TypeScript 类型?

​​答案​​:

定义组件类型:

javascript 复制代码
import { DefineComponent } from 'vue'

interface Props {
  title: string
  count?: number
}

interface Emits {
  (e: 'update', value: string): void
}

const MyComponent: DefineComponent<Props, {}, {}, {}, {}, {}, {}, Emits> = {
  props: {
    title: String,
    count: Number
  },
  emits: ['update'],
  setup(props, { emit }) {
    // 类型推断可用
  }
}

Vue 3.3+ 更简洁:

javascript 复制代码
defineProps<{
  title: string
  count?: number
}>()

defineEmits<{
  update: [value: string]
}>()

78. 如何为 Vuex/Pinia 添加 TypeScript 支持?

​​答案​​:

Vuex 类型支持:

javascript 复制代码
interface State {
  count: number
}

const store = createStore<State>({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++ // 类型推断
    }
  }
})

Pinia 类型支持:

javascript 复制代码
export const useStore = defineStore('main', {
  state: (): State => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++ // 类型推断
    }
  }
})

组件中使用:

javascript 复制代码
const store = useStore()
store.count // 类型安全

79. 如何为自定义 hook 添加类型?

​​答案​​:

自定义 hook 类型:

javascript 复制代码
import { ref, Ref } from 'vue'

interface UseCounterOptions {
  initialValue?: number
  step?: number
}

interface UseCounterReturn {
  count: Ref<number>
  increment: () => void
  decrement: () => void
}

export function useCounter(options: UseCounterOptions = {}): UseCounterReturn {
  const count = ref(options.initialValue || 0)
  
  function increment() {
    count.value += options.step || 1
  }
  
  function decrement() {
    count.value -= options.step || 1
  }
  
  return {
    count,
    increment,
    decrement
  }
}

80. Vue 3 中如何类型化全局属性和方法?

​​答案​​:

类型化全局属性:

javascript 复制代码
// main.ts
app.config.globalProperties.$filters = {
  formatDate(date: Date): string {
    return date.toLocaleDateString()
  }
}

// 类型声明
declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $filters: {
      formatDate: (date: Date) => string
    }
  }
}

// 组件中使用
const { proxy } = getCurrentInstance()
proxy.$filters.formatDate(new Date())

81. 如何实现权限控制系统?

​​答案​​:

权限控制实现方案:

复制代码
路由级别:
javascript 复制代码
{
  path: '/admin',
  meta: { requiresAdmin: true }
}

router.beforeEach((to) => {
  if (to.meta.requiresAdmin && !user.isAdmin) {
    return '/login'
  }
})

组件级别:

javascript 复制代码
<template>
  <admin-panel v-if="user.isAdmin" />
</template>

指令级别:

javascript 复制代码
Vue.directive('permission', {
  inserted(el, binding) {
    if (!checkPermission(binding.value)) {
      el.parentNode.removeChild(el)
    }
  }
})
复制代码
动态菜单:
    根据权限生成菜单
    后端返回可访问路由

82. 如何实现多主题切换功能?

​​答案​​:

主题切换实现:

复制代码
CSS 变量方案:
javascript 复制代码
:root {
  --primary-color: #42b983;
}

.theme-dark {
  --primary-color: #333;
}

function toggleTheme() {
  document.body.classList.toggle('theme-dark')
}

类名切换:

vue 复制代码
<div :class="[themeClass]"></div>

动态样式表:

javascript 复制代码
function loadTheme(themeName) {
  const link = document.createElement('link')
  link.href = `/themes/${themeName}.css`
  link.rel = 'stylesheet'
  document.head.appendChild(link)
}
复制代码
状态管理:
    将主题信息存储在 Vuex/Pinia
    持久化到 localStorage

83. 如何实现全局加载状态?

​​答案​​:

全局加载状态实现:

复制代码
使用状态管理:
vue 复制代码
// store
state: { isLoading: false },
mutations: {
  SET_LOADING(state, value) {
    state.isLoading = value
  }
}

// 组件
<loading-spinner v-if="$store.state.isLoading" />

使用 provide/inject:

// 根组件
provide('isLoading', ref(false))

// 子组件
const isLoading = inject('isLoading')

使用事件总线:

// 请求拦截器
axios.interceptors.request.use(config => {
  eventBus.emit('loading', true)
  return config
})

组合式函数:

javascript 复制代码
export function useLoading() {
  const isLoading = ref(false)
  
  function withLoading(fn) {
    return async (...args) => {
      isLoading.value = true
      try {
        await fn(...args)
      } finally {
        isLoading.value = false
      }
    }
  }
  
  return { isLoading, withLoading }
}

84. 如何实现表单验证系统?

​​答案​​:

表单验证方案:

复制代码
使用 Vuelidate:
vue 复制代码
import { required, email } from '@vuelidate/validators'

export default {
  setup() {
    return {
      v$: useVuelidate()
    }
  },
  data() {
    return { email: '' }
  },
  validations: {
    email: { required, email }
  }
}

使用 VeeValidate:

vue 复制代码
<Form @submit="onSubmit">
  <Field name="email" rules="required|email" />
  <ErrorMessage name="email" />
</Form>

自定义验证:

vue 复制代码
function validate(form) {
  const errors = {}
  if (!form.name) errors.name = 'Required'
  return errors
}

异步验证:

javascript 复制代码
async function checkEmailUnique(email) {
  const res = await api.checkEmail(email)
  return res.available
}

85. 如何实现拖拽排序功能?

​​答案​​:

拖拽排序实现:

复制代码
使用 SortableJS:
vue 复制代码
import Sortable from 'sortablejs'

onMounted(() => {
  Sortable.create(el, {
    onEnd: (e) => {
      // 处理排序
    }
  })
})

使用 Vue Draggable:

vue 复制代码
<draggable v-model="list" @end="onDragEnd">
  <div v-for="item in list" :key="item.id">
    {{ item.name }}
  </div>
</draggable>

原生实现:

javascript 复制代码
function handleDragStart(e) {
  e.dataTransfer.setData('text/plain', e.target.id)
}

function handleDrop(e) {
  const id = e.dataTransfer.getData('text/plain')
  // 重新排序
}

移动端支持:

复制代码
使用 touch 事件
使用 Hammer.js 等库

86. 如何设计大型 Vue 应用的目录结构?

​​答案​​:

推荐目录结构:

src/

├── assets/ # 静态资源

├── components/ # 公共组件

│ ├── ui/ # 基础UI组件

│ └── ... # 其他组件

├── composables/ # 组合式函数

├── stores/ # 状态管理

├── router/ # 路由配置

├── views/ # 页面组件

├── services/ # API服务

├── utils/ # 工具函数

├── styles/ # 全局样式

├── types/ # 类型定义

├── App.vue # 根组件

└── main.ts # 入口文件

模块化方案:

复制代码
按功能模块划分:

src/modules/
├── auth/
│   ├── components/
│   ├── store/
│   └── services/
└── user/
    ├── components/
    ├── store/
    └── services/

按业务领域划分

混合方式

87. 如何实现微前端架构中的 Vue 应用?

​​答案​​:

Vue 微前端方案:

复制代码
使用 qiankun:
javascript 复制代码
// 主应用
registerMicroApps([
  {
    name: 'vue-app',
    entry: '//localhost:7101',
    container: '#subapp',
    activeRule: '/vue'
  }
])

// 子应用
export async function mount(props) {
  render(props)
}

使用 Module Federation:

javascript 复制代码
// webpack 配置
new ModuleFederationPlugin({
  name: 'host',
  remotes: {
    app1: 'app1@http://localhost:3001/remoteEntry.js'
  }
})
复制代码
其他方案:
    single-spa
    iframe

关键点:

复制代码
样式隔离
状态隔离
路由协调
公共依赖

88. 如何设计可复用的组件库?

​​答案​​:

组件库设计要点:

复制代码
组件设计原则:
    单一职责
    可组合
    明确的接口
    良好的文档

技术实现:
    使用 Vue CLI/Vite 打包
    支持按需导入
    类型定义
    主题定制

文档:
    Storybook
    示例代码
    API 文档

发布:
    npm 包
    版本管理
    changelog

测试:
    单元测试
    可视化测试
    端到端测试

89. 如何实现 Vue 应用的国际化?

​​答案​​:

国际化方案:

复制代码
使用 vue-i18n:
vue 复制代码
import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  locale: 'en',
  messages: {
    en: { welcome: 'Welcome' },
    zh: { welcome: '欢迎' }
  }
})

app.use(i18n)

组件中使用:

vue 复制代码
<p>{{ $t('welcome') }}</p>

动态切换语言:

复制代码
i18n.global.locale = 'zh'

高级功能:
    懒加载语言包
    复数处理
    日期/数字格式化

90. 如何实现 Vue 和原生应用的混合开发?

​​答案​​:

混合开发方案:

复制代码
WebView 嵌入:
    原生应用内嵌 WebView
    Vue 应用适配移动端

原生桥接:
javascript 复制代码
// Android
window.androidBridge.callNativeMethod()

// iOS
window.webkit.messageHandlers.nativeHandler.postMessage()

使用 Capacitor:

javascript 复制代码
import { Plugins } from '@capacitor/core'
const { Camera } = Plugins

async takePhoto() {
  const image = await Camera.getPhoto()
}

其他方案:

复制代码
Cordova
NativeScript-Vue
Weex

91. Vue 3 的编译器优化有哪些?

​​答案​​:

Vue 3 编译器优化:

复制代码
静态节点提升:
    将静态节点提升到渲染函数外
    避免重复创建 VNode

补丁标志:
    标记动态节点类型
    减少 diff 时需要比较的内容

区块树:
    将动态节点按结构划分区块
    减少需要追踪的动态节点数量

缓存事件处理函数:
    避免不必要的重新渲染

更快的 SSR 渲染

92. Vue 3 的静态提升是什么原理?

​​答案​​:

静态提升原理:

复制代码
编译时分析模板:
    识别完全静态的节点
    识别只有 class/style 动态的节点

提升静态节点:

const _hoisted_1 = createVNode("div", null, "static content")

function render() {
  return _hoisted_1
}

运行时直接复用:
    跳过这些节点的 diff/patch
    大幅提升更新性能

效果:

复制代码
减少 VNode 创建开销
减少内存占用
提高渲染性能

93. Vue 3 的区块树优化是什么?

​​答案​​:

区块树 (Block Tree) 优化:

复制代码
将模板划分为区块:
    每个区块包含动态节点
    静态内容作为整体处理

动态节点收集:
    编译时收集动态节点引用
    形成扁平数组结构

更新时:
    直接遍历动态节点数组
    跳过静态内容比较

优势:

复制代码
减少虚拟 DOM 树遍历
更精确的更新目标
提高 diff 效率

94. Vue 3 的按需编译是什么?如何实现?

​​答案​​:

按需编译原理:

复制代码
基于 ES 模块的 tree-shaking:
    只打包实际使用的代码
    移除未使用的功能

编译器优化:
    根据模板实际使用的功能生成代码
    例如不使用 v-model 就不编译相关代码

组合式 API 设计:
    按需导入功能函数
    更好的 tree-shaking

实现方式:

复制代码
使用 Vite/Rollup
配置优化选项:
javascript 复制代码
// vite.config.js
export default {
  build: {
    rollupOptions: {
      treeshake: true
    }
  }
}

95. Vue 3 的 CSS 变量注入是什么?如何使用?

​​答案​​:

CSS 变量注入允许在 JS 中定义 CSS 变量并在样式中使用。

使用:

javascript 复制代码
<script setup>
import { ref } from 'vue'

const color = ref('red')
</script>

<template>
  <div class="text">Hello</div>
</template>

<style>
.text {
  color: v-bind(color);
}
</style>

编译为:

javascript 复制代码
.text {
  color: var(--xxxxxx);
}

原理:

复制代码
编译时将 v-bind 转换为 CSS 变量
运行时动态更新变量值

优势:

复制代码
更好的 JS-CSS 集成
动态主题支持
类型安全

综合问题

96. Vue 3 相比 React 有哪些优势和劣势?

​​答案​​:

Vue 3 优势:

复制代码
更简单的学习曲线
更灵活的模板和 JSX 支持
更精细的响应式系统
更小的运行时体积
更好的性能优化
组合式 API 更灵活

React 优势:

复制代码
更大的生态系统
更丰富的第三方库
更成熟的移动端方案
更灵活的渲染目标
更早引入的并发特性

选择考虑:

复制代码
偏好模板语法选 Vue
需要最大灵活性选 React
性能敏感场景 Vue 可能更优
大型团队 React 可能更合适

97. Vue 3 和 Svelte 的主要区别是什么?

​​答案​​:

主要区别:

复制代码
编译策略:
    Svelte 编译为高效命令式代码
    Vue 保留运行时

响应式:
    Svelte 使用编译时响应式
    Vue 使用运行时响应式系统

状态管理:
    Svelte 使用简单的 store
    Vue 提供 Vuex/Pinia

生态系统:
    Vue 有更成熟的生态系统
    Svelte 更轻量

学习曲线:
    Svelte 更简单
    Vue 提供更多高级功能

98. Vue 3 未来的发展方向是什么?

​​答案​​:

Vue 未来方向:

复制代码
更好的 TypeScript 支持
更强大的编译时优化
更小的运行时体积
更好的开发工具体验
更完善的 SSR 支持
更强大的组合式 API
可能的并发渲染支持
更友好的移动端方案

社区趋势:

复制代码
Vite 成为标配
Pinia 取代 Vuex
组合式 API 成为主流
更多基于编译的优化

99. 如何成为 Vue 高级开发者?

​​答案​​:

进阶路径:

复制代码
深入理解核心原理:
    响应式系统
    虚拟 DOM
    编译器

掌握高级特性:
    自定义渲染器
    编译器宏
    源码定制

性能优化专家:
    渲染性能
    打包优化
    内存管理

架构设计能力:
    大型应用架构
    微前端
    组件库设计

社区贡献:
    参与开源
    编写插件
    分享经验

100. 如何设计一个 Vue 技术架构面试题?

​​答案​​:

好的 Vue 架构面试题应包含:

复制代码
技术选型:
    Vue 2 vs Vue 3
    状态管理方案
    构建工具选择

应用结构:
    目录组织
    代码拆分
    模块划分

性能考虑:
    加载性能
    运行时性能
    内存使用

扩展性:
    新功能添加
    团队协作
    长期维护

实际场景:
    给定业务需求
    特定约束条件
    权衡取舍
相关推荐
前端小咸鱼一条28 分钟前
React组件化的封装
前端·javascript·react.js
随便起的名字也被占用35 分钟前
leaflet中绘制轨迹线的大量轨迹点,解决大量 marker 绑定 tooltip 同时显示导致的性能问题
前端·javascript·vue.js·leaflet
JuneXcy1 小时前
11.Layout-Pinia优化重复请求
前端·javascript·css
天下无贼!1 小时前
【自制组件库】从零到一实现属于自己的 Vue3 组件库!!!
前端·javascript·vue.js·ui·架构·scss
PineappleCoder2 小时前
JS 作用域链拆解:变量查找的 “俄罗斯套娃” 规则
前端·javascript·面试
知识分享小能手2 小时前
Vue3 学习教程,从入门到精通,Vue3 中使用 Axios 进行 Ajax 请求的语法知识点与案例代码(23)
前端·javascript·vue.js·学习·ajax·vue·vue3
533_2 小时前
[echarts] 更新数据
前端·javascript·echarts
讨厌吃蛋黄酥2 小时前
利用Mock实现前后端联调的解决方案
前端·javascript·后端
zzywxc7873 小时前
在处理大数据列表渲染时,React 虚拟列表是提升性能的关键技术,但在实际实现中常遇到渲染抖动和滚动定位偏移等问题。
前端·javascript·人工智能·深度学习·react.js·重构·ecmascript
前端小巷子3 小时前
Vue 2 Diff 算法
前端·vue.js·面试