技术文档中心
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
  • Vue2 基础

    • Vue 学习指南
    • Vue2 快速入门
    • Vue2 模板语法
    • Vue2 组件基础
    • Vue2 计算属性与侦听器
    • Vue2 生命周期
  • Vue2 进阶

    • Vue2 组件通信
    • Vue2 插槽详解
    • Vue2 混入与自定义指令
    • Vue2 过渡与动画
    • Vuex 状态管理
  • Vue2 高级

    • Vue2 性能优化
    • Vue2 服务端渲染(SSR)
    • Vue2 源码解析
  • Vue3 基础

    • Vue3 快速入门
    • Vue3 Composition API
    • Vue3 响应式系统
    • Vue3 组件基础
    • Vue3 生命周期
  • Vue3 进阶

    • Vue3 组合式函数
    • Vue3 组件通信
    • Vue3 Teleport 与 Suspense
    • Pinia 状态管理
    • Vue Router 4
  • Vue3 高级

    • Vue3 TypeScript
    • Vue3 性能优化
    • Vue3 测试
    • Vue3 SSR
    • Vue3 源码解析
  • 实战项目

    • Vue2 实战项目
    • Vue3 实战项目
    • Vue2 迁移 Vue3

Vue3 响应式系统

响应式原理

Vue3 使用 Proxy 实现响应式,相比 Vue2 的 Object.defineProperty 有以下优势:

  • 可以监听数组索引和长度的变化
  • 可以监听对象属性的添加和删除
  • 更好的性能

核心 API

ref

import { ref } from 'vue'

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

count.value++
console.log(count.value) // 1

// 在模板中自动解包
<template>
  <div>{{ count }}</div>
</template>

reactive

import { reactive } from 'vue'

const state = reactive({
  count: 0,
  nested: {
    value: 1
  }
})

state.count++
state.nested.value++

shallowRef

import { shallowRef } from 'vue'

const state = shallowRef({ count: 0 })

// 不会触发更新
state.value.count++

// 会触发更新
state.value = { count: 1 }

shallowReactive

import { shallowReactive } from 'vue'

const state = shallowReactive({
  count: 0,
  nested: { value: 1 }
})

// 会触发更新
state.count++

// 不会触发更新
state.nested.value++

toRef / toRefs

import { reactive, toRef, toRefs } from 'vue'

const state = reactive({
  foo: 1,
  bar: 2
})

// 创建单个 ref
const fooRef = toRef(state, 'foo')
fooRef.value++ // state.foo 也会更新

// 解构保持响应性
const { foo, bar } = toRefs(state)

unref

import { ref, unref } from 'vue'

const count = ref(0)
console.log(unref(count)) // 0

const num = 1
console.log(unref(num)) // 1

isRef / isReactive / isProxy

import { ref, reactive, isRef, isReactive, isProxy } from 'vue'

const count = ref(0)
const state = reactive({})

console.log(isRef(count)) // true
console.log(isReactive(state)) // true
console.log(isProxy(count)) // false
console.log(isProxy(state)) // true

响应式工具

toRaw

import { reactive, toRaw } from 'vue'

const state = reactive({ count: 0 })
const raw = toRaw(state)

console.log(raw === state) // false
raw.count++ // 不会触发更新

markRaw

import { reactive, markRaw } from 'vue'

const obj = markRaw({ count: 0 })
const state = reactive({ obj })

// obj 不会被转换为响应式
state.obj.count++ // 不会触发更新

effectScope

import { effectScope, ref, watchEffect } from 'vue'

const scope = effectScope()

scope.run(() => {
  const count = ref(0)
  
  watchEffect(() => {
    console.log(count.value)
  })
})

// 停止所有副作用
scope.stop()

高级用法

customRef

import { 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('hello')

triggerRef

import { shallowRef, triggerRef } from 'vue'

const state = shallowRef({ count: 0 })

state.value.count++
triggerRef(state) // 手动触发更新
最近更新: 2026/1/27 15:51
Contributors: hailong
Prev
Vue3 Composition API
Next
Vue3 组件基础