vue3响应式数据(ref,reactive)详解

ref

概念:

  • 用于创建响应式的基本类型数据(如 string, number, boolean)

  • 也可以用于对象和数组,但更推荐对基本类型使用

  • 返回一个响应式的、可变的 ref 对象,该对象内部通过 .value 属性持有其值

  • 模板中的 ref 属性(如 <div ref="myDiv">)会创建 DOM 元素的引用,这与响应式的 ref 是不同的概念

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

const count = ref(0) // 创建
console.log(count.value) // 访问
count.value++ // 修改

特点:

  1. 在模板中使用时自动解包,无需 .value

  2. 在响应式对象中使用时自动解包

    javascript 复制代码
    ​
    const state = reactive({
      foo: 1,
      bar: 2
    })
    
    //直接使用即可,不需要state.foo.value++
    ​state.foo++
    console.log(​state.foo)// 2
  3. 适合用于基本类型数据和需要在多处引用的响应式数据

reactive

概念:

  • 用于创建响应式的对象(包括数组)

  • 返回对象的响应式代理

  • 只能用于对象类型(Object, Array, Map, Set 等)

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

const state = reactive({
  count: 0,
  name: 'Vue'
}) // 创建
console.log(state.count) // 访问
state.count++ // 修改

特点:

  1. 直接访问和修改属性,不需要 .value

  2. 解构或属性赋值会失去响应性

  3. 适合用于复杂对象和局部状态

toRef 和 toRefs

toReftoRefs 是 Vue3 组合式 API 中用于处理响应式引用的两个实用函数,它们可以帮助我们在解构或传递响应式对象时保持其响应性。

toRef

toRef 用于为响应式对象上的某个属性创建一个 ref 引用,这个 ref 会与源属性保持同步。

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

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

// 创建一个与 state.foo 保持同步的 ref
const fooRef = toRef(state, 'foo')

// 修改 ref 会更新原始属性
fooRef.value++
console.log(state.foo) // 2

// 修改原始属性也会更新 ref
state.foo++
console.log(fooRef.value) // 3

toRefs

toRefs 将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向原始对象相应属性的 ref。

简单理解,如图所示:

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

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

const stateRefs = toRefs(state)

// ref 和原始属性保持同步
stateRefs.foo.value++
console.log(state.foo) // 2

state.bar++
console.log(stateRefs.bar.value) // 3

注意事项:

  1. 这两个函数只对响应式对象(reactive 创建)有效,对普通对象无效

  2. 使用解构赋值时,toRefs 可以保持响应性,而直接解构会失去响应性

  3. 对于可能不存在的属性,可以使用 toRef 并提供默认值:

    javascript 复制代码
    const fooRef = toRef(state, 'nonExistent', 'default value')

实际应用:

  1. 基本类型 优先使用 ref

  2. 复杂对象(层级较深) 使用 reactive

  3. 组合式函数返回状态时优先返回 ref,方便解构

  4. 使用 isRefisReactive 进行类型检查

相关推荐
掘金挖土18 分钟前
前端手摸手跑路之 AI 应用开发(二)
前端·后端
兜里只有三分钱~27 分钟前
翻卡_3D 的仪式感,和三个让它穿帮的写法
javascript·css·3d
mayaairi1 小时前
Vue2 组件通讯(四):v-model、scoped样式、mixins与plugins
前端·javascript·vue.js
梦曦i1 小时前
@meng-xi/uni-router 未来展望:夯实基础、深化体验、探索前沿
前端·uni-app
前端炒粉1 小时前
DOM 常用 API 速查表
开发语言·javascript·ecmascript
Yeyu1 小时前
AAOS AppCard 实践:怎么把自己的 App 塞进别人的卡片里
前端
星云API技术支持1 小时前
企业微信二次开发:如何建立统一的错误处理、日志与请求追踪机制
javascript·企业微信·ruby
IT_陈寒2 小时前
Vite静态资源路径这个大坑害我调了一下午
前端·人工智能·后端
武哥聊编程2 小时前
【AI实战项目】基于SpringAI+Springboot+Vue的AI面试刷题训练平台
vue.js·人工智能·spring boot·springai
狗哥哥2 小时前
分享下我的读书清单
前端