Vue3 响应式API-Refs

924 阅读2分钟

这是我参与8月更文挑战的第1天,活动详情查看: 8月更文挑战

什么是响应式

响应性是一种允许我们以声明式的方式去适应变化的编程范例。
当一个值依附另一个值进行计算时, 如果前一个值发生了变化, 依附的那个也会同时进行变更.
典型案例参见 excel 函数. 当单元格A3=SUM(A1:A2)时, 此时更改A1或A2任意一个发生改变时, A3会立即作出响应更新.

响应式是Vue3的核心API。
官方也把此响应式API进行单独打包,即便不使用Vue3的情况下也可以独立使用:@vue/reactivity

什么是Refs

Refs 是Vue3中核心方法,是响应式API的心脏。

Refs有5个关键方法:

  • ref()
  • unref()
  • isRef()
  • toRef()
  • toRefs()

ref 让对象具备响应式

传递一个值返回该值响应式且可变的 ref 对象。ref 对象具有指向内部值的单个 property .value

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

count.value++
console.log(count.value) // 1
复制代码

unref 返回一个对象内部值

这是 val = isRef(val) ? val.value : val 的语法糖函数。

const unwrapped = unref(x) // unwrapped 现在一定是数字类型
复制代码

isRef 检查值是否为一个 ref 对象。

const source = 0;
const foo = ref(source)
const unfoo = unref(foo)

isRef(foo) // true
isRef(source) // false
isRef(unfoo) // false
复制代码

toRef 为源响应式对象上的某个 property 新创建一个 ref

ref 可以被传递,它会保持对其源 property 的响应式连接。

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

const fooRef = toRef(state, 'foo')

fooRef.value++
console.log(state.foo) // 2

state.foo++
console.log(fooRef.value) // 3
复制代码

toRefs 解构响应式对象

将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref

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

const stateAsRefs = toRefs(state)
/*
stateAsRefs 的类型:

{
  foo: Ref<number>,
  bar: Ref<number>
}
*/

// ref 和原始 property 已经“链接”起来了
state.foo++
console.log(stateAsRefs.foo.value) // 2

stateAsRefs.foo.value++
console.log(state.foo) // 3
复制代码

当从组合式函数返回响应式对象时,toRefs 非常有用,这样消费组件就可以在不丢失响应性的情况下对返回的对象进行分解/扩散:

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

  // 操作 state 的逻辑

  // 返回时转换为ref
  return toRefs(state)
}

export default {
  setup() {
    // 可以在不失去响应性的情况下解构
    const { foo, bar } = useFeatureX()

    return {
      foo,
      bar
    }
  }
}
复制代码

toRefs 只会为源对象中包含的 property 生成 ref。如果要为特定的 property 创建 ref,则应当使用 toRef

文献