1. Vue 3的组合式API(Composition API)与选项式API(Options API)的核心区别是什么?在什么场景下推荐使用组合式API?
- :
组合式API通过setup()
函数组织逻辑,允许按功能拆分代码(如ref
,reactive
,computed
),解决选项式API中逻辑分散的问题(如data
、methods
分离)。
适合复杂组件、逻辑复用(自定义Hook)或TypeScript项目,提升代码可维护性。
2. Vue 3的响应式数据中,ref
和reactive
有什么区别?如何决定使用哪一个?
-
:
ref
:包装基本类型(如string
,number
),通过.value
访问,可用于任何数据类型。reactive
:仅接收对象类型,自动深层响应式,直接访问属性,解构可能丢失响应性。- 选择 :基本类型用
ref
;复杂对象用reactive
,需保持引用时用toRefs
解构。
3. Vue 3中如何监听响应式数据的变化?watch
和watchEffect
有何区别?
-
:
watch
:需指定监听的具体数据源和回调,可配置immediate
和deep
。watchEffect
:自动追踪回调内的依赖,立即执行,适用于依赖动态变化的场景。- 区别 :
watch
精确控制依赖,watchEffect
自动收集依赖,更简洁。
4. Vue 3的setup
函数中如何访问组件实例的props
和context
?
-
答案 :
setup(props, context)
:props
:响应式对象,不可解构,需用toRefs
保持响应性。context
:包含attrs
、slots
、emit
等非响应式属性。
5. Vue 3的Teleport组件有什么作用?举一个实际应用场景。
-
:
作用 :将子组件渲染到DOM的指定位置(如body末尾),解决模态框、弹窗的样式层级问题。
示例:
ini
<teleport to="#modal-container">
<div v-if="showModal">模态框内容</div>
</teleport>
6. Vue 3如何实现多个v-model
绑定?
-
:
通过给
v-model
添加参数:
ini
<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />
子组件用emit('update:title', newValue)
触发更新。
7. 解释Vue 3的响应式原理,对比Vue 2的Object.defineProperty
。
-
:
- Vue 3 :使用
Proxy
代理对象,支持监听属性新增/删除、数组索引变化,无需递归初始化。 - Vue 2 :
Object.defineProperty
无法检测数组索引/对象属性增减,需用Vue.set
。
- Vue 3 :使用
8. Vue 3中如何优化组件渲染性能?举两个例子。
-
答案:
- v-memo:缓存静态内容,避免重复渲染。
css
<div v-memo="[value]">{{ value }}</div>
- 异步组件 :使用
defineAsyncComponent
延迟加载非关键组件。 - 优化策略 :减少响应式数据嵌套、合理使用
shallowRef
/shallowReactive
。
9. 如何用Vue 3的自定义Hook实现逻辑复用?编写一个鼠标位置跟踪的Hook。
- :
ini
// useMousePosition.js
import { ref, onMounted, onUnmounted } from 'vue';
export function useMousePosition() {
const x = ref(0);
const y = ref(0);
const update = (e) => {
x.value = e.clientX;
y.value = e.clientY;
};
onMounted(() => window.addEventListener('mousemove', update));
onUnmounted(() => window.removeEventListener('mousemove', update));
return { x, y };
}
// 组件内使用
const { x, y } = useMousePosition();
10. Vue 3的<script setup>
语法糖解决了哪些问题?举例说明其用法。
-
:
优势 :简化组合式API的样板代码,自动暴露顶层变量。
示例:
xml
<script setup>
import { ref } from 'vue';
const count = ref(0);
// 直接使用,无需return
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>