
1. ref, reactive, toRef, toRefs
- ref - 创建响应式引用
- reactive - 创建响应式对象
- toRef - 创建指向响应式对象属性的引用
- toRefs - 将响应式对象转换为普通对象(包含 ref)
1.1 ref
- 作用:创建一个响应式的引用对象,可以包装基本类型或对象类型。
- 特点 :
- 返回一个带有 .value属性的对象
- 在模板中自动解包(无需使用 .value)
- 适合包装基本类型值(字符串、数字等)
- 也可以包装对象,但内部会使用 reactive转换
js
import { ref } from 'vue'
// 基本类型
const count = ref(0)
console.log(count.value) // 0
// 对象类型
const user = ref({ name: 'John', age: 30 })
console.log(user.value.name) // John
1.2 reactive
- 作用 :创建一个深层次的响应式对象(Proxy 代理)。
- 特点 :
- 只能用于对象类型(对象、数组、Map、Set)
- 不需要 .value访问
- 嵌套对象也会被自动转换为响应式
- 不适合解构(会失去响应性)
js
import { reactive } from 'vue'
const state = reactive({
count: 0,
user: {
name: 'John',
age: 30
}
})
// 直接访问属性
state.count++ // 响应式更新
console.log(state.user.name) // John
1.3 toRef
- 作用:为响应式对象的某个属性创建一个 ref,保持与源属性的响应式连接。
- 特点 :
- 保持对源属性的响应式连接
- 修改 ref 会更新源对象,反之亦然
- 当需要将 prop 转换为 ref 时特别有用
js
import { reactive, toRef } from 'vue'
const state = reactive({
count: 0
})
// 创建指向 state.count 的 ref
const countRef = toRef(state, 'count')
countRef.value++ // 会更新 state.count
console.log(state.count) // 1
state.count = 10 // 也会更新 countRef.value
console.log(countRef.value) // 10
1.4 toRefs
- 作用:将响应式对象的每个属性转换为 ref,保持响应式连接。
- 特点 :
- 解决 reactive 对象解构时失去响应性的问题
- 返回的对象每个属性都是 ref
- 在组合函数中返回响应式状态时特别有用
js
import { reactive, toRefs } from 'vue'
const state = reactive({
count: 0,
name: 'John'
})
// 将响应式对象转换为 ref 对象
const stateRefs = toRefs(state)
// 解构后仍然保持响应性
const { count, name } = toRefs(state)
count.value++ // 会更新 state.count
name.value = 'Alice' // 会更新 state.name
2. computed, watch, watchEffect,
- computed - 计算属性
- watch - 侦听器
- watchEffect - 立即执行侦听器
2.1 computed
- 作用:创建基于其他响应式数据的派生值,具有缓存机制。
- 特点 :
- 惰性求值:只有依赖变化时才会重新计算
- 自动追踪依赖
- 返回一个只读的响应式 ref
- 适合同步计算
js
import { ref, computed } from 'vue'
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
console.log(doubleCount.value) // 0
count.value = 5
console.log(doubleCount.value) // 10
2.2 watch
- 作用:观察特定数据源的变化,执行回调函数。
- 特点 :
- 需要明确指定侦听的数据源
- 可以获取变化前后的值
- 支持深度侦听
- 支持异步操作
- 可以手动停止侦听
js
import { ref, watch } from 'vue'
const count = ref(0)
// 基本用法
watch(count, (newValue, oldValue) => {
console.log(`count从${oldValue}变为${newValue}`)
})
// 侦听多个源
const name = ref('John')
watch([count, name], ([newCount, newName], [oldCount, oldName]) => {
// 处理变化
})
// 深度侦听对象
const user = ref({ name: 'Alice', age: 30 })
watch(user, (newUser) => {
console.log('用户信息变化', newUser)
}, { deep: true })
// 立即执行
watch(count, callback, { immediate: true })
2.3 watchEffect
- 作用:立即执行一个函数,并自动追踪其依赖,依赖变化时重新执行。
- 特点 :
- 立即执行
- 自动收集依赖
- 没有新旧值参数
- 支持异步操作
- 可以手动停止
js
import { ref, watchEffect } from 'vue'
const count = ref(0)
const name = ref('John')
// 基本用法
watchEffect(() => {
console.log(`count: ${count.value}, name: ${name.value}`)
})
// 停止侦听
const stop = watchEffect(() => { /* ... */ })
stop() // 停止侦听
// 清理副作用
watchEffect((onInvalidate) => {
const timer = setTimeout(() => {
console.log('执行操作')
}, 1000)
onInvalidate(() => {
clearTimeout(timer) // 清理操作
})
})
- 使用场景 :
- 需要立即执行的副作用
- 依赖关系复杂时
- 不需要知道具体变化的值时
- 需要自动收集依赖时
3. shallowRef, shallowReactive
-
shallowRef - 创建浅层响应式引用,只对 .value本身进行响应式处理
jsimport { shallowRef } from 'vue' const largeObject = shallowRef({ nested: { data: 'value' } // 嵌套对象不会被响应式处理 }) // 改变顶层属性会触发响应 largeObject.value = { ... } // 改变嵌套属性不会触发响应 largeObject.value.nested.data = 'new value' // 不会触发更新
-
shallowReactive - 创建浅层响应式对象,只对顶层属性进行响应式处理
jsimport { shallowReactive } from 'vue' const state = shallowReactive({ topLevel: 'value', nested: { data: 'value' } // 嵌套对象不会被响应式处理 }) // 改变顶层属性会触发响应 state.topLevel = 'new value' // 改变嵌套属性不会触发响应 state.nested.data = 'new value' // 不会触发更新
4. readonly, shallowReadonly
-
readonly - 创建只读的响应式代理
- 任何修改尝试都会失败并产生警告
- 深度只读(所有嵌套属性都是只读的)
jsimport { reactive, readonly } from 'vue' const original = reactive({ count: 0 }) const copy = readonly(original) copy.count++ // 警告:Set operation on key "count" failed
-
shallowReadonly - 创建浅层只读的响应式代理
- 顶层属性只读
- 嵌套属性可修改(非只读)
jsimport { shallowReadonly } from 'vue' const state = shallowReadonly({ topLevel: 'value', nested: { data: 'value' } }) state.topLevel = 'new' // 警告:Set operation failed state.nested.data = 'new' // 允许修改
5. customRef
-
customRef - 创建自定义的 ref,显式控制依赖追踪和更新触发
- 提供 track和 trigger函数手动控制
- 适合实现防抖、节流等高级功能
jsimport { customRef } from 'vue' function useDebouncedRef(value, delay = 200) { let timeout return customRef((track, trigger) => { return { get() { track() // 追踪依赖 return value }, set(newValue) { clearTimeout(timeout) timeout = setTimeout(() => { value = newValue trigger() // 触发更新 }, delay) } } }) } // 使用示例 const text = useDebouncedRef('', 500)
6. effectScope
-
effectScope - 创建一个作用域,可以捕获其中创建的所有响应式 effect
- 可以统一停止所有 effect
- 适合在组件作用域外管理 effect
jsimport { effectScope, ref, watch } from 'vue' const scope = effectScope() scope.run(() => { const count = ref(0) watch(count, () => { console.log('count changed') }) // 其他 effect... }) // 停止所有 effect scope.stop()
7. getCurrentScope, onScopeDispose
- getCurrentScope - 获取当前活动的 effect 作用域
- onScopeDispose - 在当前作用域销毁时注册回调函数(在组合式函数中清理资源)
js
import { getCurrentScope, onScopeDispose } from 'vue'
function useEventListener(target, event, callback) {
target.addEventListener(event, callback)
// 如果有当前作用域,注册清理函数
if (getCurrentScope()) {
onScopeDispose(() => {
target.removeEventListener(event, callback)
})
}
}
8. provide, inject
依赖注入
9. nextTick
等待下一次 DOM 更新刷新(等DOM更新完成之后,再执行的回调函数)
10. useAttrs, useSlots
- useAttrs - 访问组件接收的非 props 属性
- useSlots - 访问组件的插槽内容
js
import { useAttrs, useSlots } from 'vue'
const attrs = useAttrs()
const slots = useSlots()
console.log(attrs.class) // 获取 class 属性
console.log(slots.default) // 获取默认插槽
11. defineModel
- defineModel - 简化自定义组件的双向绑定(v3.4新增)
- 自动处理 modelValue和 update:modelValue
- 支持修饰符
js
// 子组件
const model = defineModel()
// 父组件
<ChildComponent v-model="value" />
12. withDirectives
- withDirectives - 在渲染函数中应用自定义指令
js
import { withDirectives, h } from 'vue'
import { vTooltip } from './directives/tooltip'
export default {
render() {
return withDirectives(h('div'), [
[vTooltip, 'This is a tooltip']
])
}
}
13. renderList
- renderList - 高效渲染列表(优化列表渲染性能)
js
import { renderList } from 'vue'
export default {
render() {
return renderList(items, (item, index) => {
return h('div', { key: item.id }, item.text)
})
}
}
14. resolveComponent, resolveDirective 调试工具
- resolveComponent - 按名称解析已注册的组件
- resolveDirective - 按名称解析已注册的指令
js
import { resolveComponent, h } from 'vue'
export default {
render() {
const ButtonComponent = resolveComponent('MyButton')
return h(ButtonComponent, { onClick: handleClick }, 'Click me')
}
}
15. onRenderTracked, onRenderTriggered 样式处理
- 调试钩子,用于追踪组件的渲染依赖和触发重新渲染的原因(性能分析和调试)
js
import { onRenderTracked, onRenderTriggered } from 'vue'
onRenderTracked((event) => {
console.log('依赖被追踪', event)
})
onRenderTriggered((event) => {
console.log('重新渲染被触发', event)
})
16. useCssModule, useCssVars
-
useCssModule - 在
<script setup>
中访问 CSS 模块(在组合式 API 中使用作用域 CSS)jsimport { useCssModule } from 'vue' const $style = useCssModule() // 在模板中使用 <template> <div :class="$style.container"></div> </template>
-
useCssVars - 在组合式 API 中动态设置 CSS 变量(主题切换和动态样式)
jsimport { useCssVars } from 'vue' useCssVars((_ctx) => ({ '--primary-color': theme.value.primary, '--secondary-color': theme.value.secondary }))