一、基础 & 常见问题

1. Vue3 的响应式是怎么实现的?

考点Proxy 替代 Vue2 的 Object.defineProperty

import { reactive } from 'vue';

const state = reactive({
  count: 0,
  nested: { msg: 'hello' }
});

state.count++; // 自动触发依赖收集 & 更新视图

区别

  • Vue2:通过 Object.defineProperty 劫持属性(无法监听新增/删除属性)。

  • Vue3:基于 Proxy,可监听数组方法、新增属性、删除属性。


2. Vue3 中 refreactive 的区别?多方面区别详解

import { ref, reactive } from 'vue';

const count = ref(0); 
console.log(count.value); // 需要 .value

const obj = reactive({ a: 1 });
console.log(obj.a); // 直接访问

总结

  • ref:处理 基本类型,返回带 .value 的对象。

  • reactive:处理 对象类型,返回 Proxy。

  • 复杂场景:reactive 内部属性还是 ref 时会自动解包。


3. Vue3 生命周期与 Vue2 对比?

import { onMounted, onUnmounted } from 'vue';

onMounted(() => {
  console.log('mounted');
});

onUnmounted(() => {
  console.log('unmounted');
});

✅ Vue3 改动:

  • Vue2:beforeCreatecreated

  • Vue3:更推荐用 setup(逻辑聚合)。


二、进阶 & 高频问题

4. computedwatch 区别?

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

const price = ref(100);
const count = ref(2);

const total = computed(() => price.value * count.value);

watch([price, count], ([newP, newC], [oldP, oldC]) => {
  console.log('变化了', newP, newC);
});

总结

  • computed:基于依赖缓存,只有依赖变化时才重新计算。

  • watch:监听副作用,更适合异步操作、深度监听。


5. Vue3 父子组件传值有哪些方式?

  • props

  • emit

  • v-model(Vue3 新增,支持多个 v-model)

  • provide/inject

  • ref 暴露组件实例

  • Pinia/Vuex 全局状态管理


6. Vue3 的 v-model 双向绑定原理?

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

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

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

✅ 本质:v-model:modelValue + @update:modelValue 的语法糖。
✅ Vue3 支持 多个 v-modelv-model:titlev-model:content


三、冷门 & 偏僻问题

7. Vue3 中 shallowReactiveshallowRef 有什么用?

import { shallowReactive, shallowRef } from 'vue';

const obj = shallowReactive({ nested: { a: 1 } });
obj.nested.a = 2; // ❌ 不会触发更新

const count = shallowRef({ num: 1 });
count.value.num = 2; // ❌ 不会触发更新

总结

  • shallowReactive:只对第一层做响应式,深层对象不会劫持。

  • shallowRef:只对 .value 变化做响应式。

  • 应用场景:大对象、性能优化。


8. Vue3 中 customRef 有什么用?

👉 用来自定义 ref 的依赖追踪逻辑。例:实现防抖输入框

import { customRef } from 'vue';

function useDebouncedRef(value, delay = 300) {
  let timeout;
  return customRef((track, trigger) => ({
    get() {
      track();
      return value;
    },
    set(newValue) {
      clearTimeout(timeout);
      timeout = setTimeout(() => {
        value = newValue;
        trigger();
      }, delay);
    }
  }));
}

const text = useDebouncedRef('', 500);

✅ 场景:表单输入防抖、节流。


9. Vue3 的 Teleport 是什么?

👉 允许组件渲染到 DOM 树的任意位置。

<template>
  <teleport to="body">
    <div class="modal">我是弹窗</div>
  </teleport>
</template>

✅ 解决:弹窗、全局提示等 脱离当前 DOM 层级 的场景。


10. Vue3 的 Suspense 是什么?

👉 处理异步组件的加载占位。

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

✅ 应用:异步数据加载、骨架屏。


四、性能优化相关问题

11. Vue3 中如何避免不必要的渲染?

  • v-memo:缓存渲染结果。

  • v-once:只渲染一次。

  • shallowRef / shallowReactive

  • markRaw:标记对象为非响应式。

  • defineComponent + defineProps 合理拆分组件。


12. Vue3 Diff 算法优化了哪些?

  • Vue2:双端对比。

  • Vue3:采用 最长递增子序列(LIS)算法 优化节点移动次数。

  • 提升列表渲染性能。


五、源码 & 底层问题(偏高级)

13. Vue3 响应式依赖收集流程?

  1. reactive 包裹对象 → 返回 Proxy。

  2. 访问属性时 → 触发 get → 执行 track(收集依赖)。

  3. 修改属性时 → 触发 set → 执行 trigger(触发更新)。

源码核心:

const bucket = new WeakMap();

function track(target, key) {
  // 收集依赖
}

function trigger(target, key) {
  // 通知更新
}

14. Vue3 setup 为什么比 Vue2 更优?

  • 更好组织逻辑(Composition API)。

  • 代码复用更强(自定义 hooks)。

  • 更利于 Tree-shaking(减少打包体积)。


15. Vue3 Tree-shaking 为什么更好?

  • Vue3 全部模块采用 ES Modules。

  • 没有用到的功能不会打包(如 keepAlivetransition)。


✅ 总结

  • 常见题ref/reactive、生命周期、computed vs watch。

  • 中阶题v-model 原理、父子通信、Teleport、Suspense。

  • 冷门题customRefshallowRefmarkRaw

  • 高级题:Diff 算法优化、响应式原理、setup 设计思想。

更多推荐