响应工API

reactive

reactive 函数返回对象的响应式副本 proxy 对象,proxy 对象不等于原始对象;proxy 响应式是深层的,会影响所有嵌套 property;

const obj = reactive({ count: 0 })


reactive 会自动解包所有深层的 refs,同时维持 ref 的响应性。

const count = ref(1)
const obj = reactive({ count })

// ref 会被解包
console.log(obj.count === count.value) // true

当将 ref 分配给 reactive property 时,ref 将被自动解包。

const count = ref(1)
const obj = reactive({})
obj.count = count

console.log(obj.count === count.value) // true


readonly

readonly用于将响应式对象、普通对象、 ref 对象包装成只读代理,与reactive相似,区别在于readonly返回的代理对象及其属性都是只读的;

const original = reactive({ count: 0 })

const copy = readonly(original)

// 变更副本将失败并导致警告
copy.count++ // 警告!


isProxy

检查对象是否是由 reactive 或 readonly 创建的 proxy ;


isReactive

检查对象是否是由 reactive 创建的响应式代理。

const state = reactive({
  name: 'John'
})
console.log(isReactive(state)) // -> true

如果该代理是 readonly 创建的,但包裹了由 reactive 创建的另一个代理,它也会返回 true

const state = reactive({
  name: 'John'
})

// 从普通对象创建的只读 proxy
const plain = readonly({
  name: 'Mary'
})
console.log(isReactive(plain)) // -> false

// 从响应式 proxy 创建的只读 proxy
const stateCopy = readonly(state)
console.log(isReactive(stateCopy)) // -> true


isReadonly

检查对象是否是由 readonly 创建的只读代理。


toRaw

返回 reactive 或 readonly 代理的原始对象,可用于临时读取数据而无需承担代理访问/跟踪的开销,也可用于写入数据而避免触发更改响应,不建议保留对原始对象的持久引用,请谨慎使用。

const foo = {}
const reactiveFoo = reactive(foo)

console.log(toRaw(reactiveFoo) === foo) // true


markRaw

标记一个对象,使其永远不会转换为 proxy,返回对象本身。

const foo = markRaw({})
console.log(isReactive(reactive(foo))) // false

// 嵌套在其他响应式对象中时也可以使用
const bar = reactive({ foo })
console.log(isReactive(bar.foo)) // false


shallowReactive(浅层Reactive)

创建一个响应式代理,它跟踪其自身 property 的响应性,但不执行嵌套对象的深层响应式转换 (暴露原始值)。

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

// 改变 state 本身的性质是响应式的
state.foo++
// ...但是不转换嵌套对象
isReactive(state.nested) // false
state.nested.bar++ // 非响应式

与 reactive 不同,使用 shallowReactive 时,任何使用 ref 的 property 都不会被代理自动解包。


shallowReadonly(浅层只读Reactive)

创建一个 proxy,使其自身的 property 为只读,但不执行嵌套对象的深度只读转换 (暴露原始值)。

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

// 改变 state 本身的 property 将失败
state.foo++
// ...但适用于嵌套对象
isReadonly(state.nested) // false
state.nested.bar++ // 适用1

与 readonly 不同,使用 shallowReadonly 时,任何使用 ref 的 property 都不会被代理自动解包。


ref

接受一个内部值并返回一个响应式且可变的 ref 对象,ref 对象仅有一个 .value property,指向该内部值。

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

如果将对象分配为 ref 值,则它将被 reactive 函数处理为深层的响应式对象。

如果泛型的类型未知,则建议将 ref 转换为 Ref<T>

function useState<State extends string>(initial: State) {
  const state = ref(initial) as Ref<State> // state.value -> State extends string
  return state
}


unref

如果参数是一个 ref,则返回内部值,否则返回参数本身

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


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

如果要将 prop 的 ref 传递给复合函数时,toRef 很有用:

setup(props) {
  useSomeFeature(toRef(props, 'foo'))
}

即使源 property 不存在,toRef 也会返回一个可用的 ref。这使得它在使用可选 prop 时特别有用,可选 prop 并不会被 toRefs 处理。


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 会为源对象中包含的 property 生成 ref,如果要为特定的 property 创建 ref,则应当使用 toRef


isRef

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


shallowRef(浅层Ref)

创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的。

const foo = shallowRef({})
// 改变 ref 的值是响应式的
foo.value = {}
// 但是这个值不会被转换。
isReactive(foo.value) // false

shallowRef浅层响应式常用于性能优化,被对象被深层递归;如下:

const state = shallowRef({ count: 1 })

// 不会触发更改
state.value.count = 2

// 会触发更改
state.value = { count: 2 }




triggerRef

默认情况下,value发生改变时 shallowRef 声明的变量才会在视图上进行更新,而 triggerRef 的作用则是手动执行与 shallowRef 关联的任何副作用,强制更新视图。


举报

© 著作权归作者所有


0