在 Vue 3 的组合式 API 中,reftoRaw 等响应式方法是开发中的核心工具。下面我将详细介绍它们的用法、区别及最佳实践场景。

1. ref

基本用法

import { ref } from 'vue'

const count = ref(0) // 创建一个响应式引用
console.log(count.value) // 访问值
count.value++ // 修改值

特点

  • 用于创建基本类型​(string, number, boolean等)的响应式数据
  • 通过 .value 访问和修改值
  • 在模板中自动解包(无需 .value

最佳场景

  1. 基本类型数据​:数字、字符串、布尔值等

    const name = ref('张三')
    const age = ref(25)
    const isActive = ref(false)
  2. DOM 引用​:

    <template>
      <input ref="inputRef">
    </template>
    
    <script setup>
    const inputRef = ref(null)
    </script>
  3. 组件引用​:

    <template>
      <ChildComponent ref="childComp" />
    </template>
    
    <script setup>
    const childComp = ref(null)
    </script>

2. toRaw

基本用法

import { reactive, toRaw } from 'vue'

const state = reactive({ count: 0 })
const rawState = toRaw(state) // 获取原始对象

特点

  • 返回 reactive 或 readonly 代理的原始对象
  • 操作原始对象不会触发响应式更新
  • 可用于临时读取大量数据避免性能开销

最佳场景

  1. 性能敏感操作​:需要读取大量数据但不触发更新

    const largeData = reactive({ /* 大数据对象 */ })
    
    function processData() {
      const raw = toRaw(largeData)
      // 对原始数据进行复杂计算
    }
  2. 第三方库集成​:需要传递非响应式对象

    const chartData = reactive({ /* ... */ })
    
    function initChart() {
      chartLib.init(toRaw(chartData)) // 某些库需要原始对象
    }
  3. 调试​:检查原始数据

    console.log('原始数据:', toRaw(reactiveObj))

3. reactive

基本用法

import { reactive } from 'vue'

const state = reactive({
  count: 0,
  user: {
    name: 'John'
  }
})

特点

  • 用于创建对象类型的响应式数据
  • 不需要 .value 访问
  • 嵌套属性也是响应式的

最佳场景

  1. 复杂对象​:表单对象、配置对象等

    const form = reactive({
      username: '',
      password: '',
      remember: false
    })
  2. 状态管理​:小型store替代方案

    const store = reactive({
      user: null,
      settings: {},
      loadUser() { /* ... */ }
    })

4. 其他常用API对比

API 作用 特点 最佳场景
shallowRef 创建浅层ref 不处理 .value 的响应式 大型对象不需要深度响应
shallowReactive 创建浅层reactive 只响应根级属性 性能优化
markRaw 标记对象永不响应 跳过代理 静态配置对象
unref ref解包 val = isRef(v) ? v.value : v 通用函数参数处理

5. 组合使用示例

场景:表单提交

import { reactive, toRaw } from 'vue'

const form = reactive({
  title: '',
  content: '',
  attachments: []
})

function submit() {
  // 提交时使用原始数据
  api.submit(toRaw(form)).then(() => {
    form.title = ''
    form.content = ''
  })
}

场景:性能优化

import { ref, shallowRef } from 'vue'

// 大数据使用shallowRef
const bigData = shallowRef({ /* 大数据结构 */ })

// 基本数据使用普通ref
const loading = ref(false)

6. 使用原则

  1. 优先选择​:

    • 基本类型 → ref
    • 对象类型 → reactive
  2. 性能优化​:

    • 只对需要响应式的数据使用响应式API
    • 大数据考虑 shallowRef/shallowReactive
    • 只读数据考虑 readonly
  3. 避免滥用​:

    • 不要过早优化(先实现功能再优化)
    • 静态数据不要用响应式API
  4. 调试技巧​:

    console.log('原始数据:', toRaw(reactiveObj))
    console.log('响应式数据:', reactiveObj)

通过合理使用这些API,可以在保证响应式能力的同时,获得最佳的开发体验和运行时性能。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐