响应式 API:工具函数
响应式 API:工具函数
isRef()
检查某个值是否为 ref。
类型
tsfunction isRef(r: Ref | unknown): r is Ref
请注意,返回值是一个类型判定 (type predicate),这意味着
isRef
可以被用作类型守卫:tslet foo: unknownif (isRef(foo)) { // foo 的类型被收窄为了 Ref foo.value}
unref()
如果参数是 ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val
计算的一个语法糖。
类型
tsfunction unref(ref: T | Ref): T
示例
tsfunction useFoo(x: number | Ref) { const unwrapped = unref(x) // unwrapped 现在保证为 number 类型}
toRef()
可以将值、refs 或 getters 规范化为 refs (3.3+)。
也可以基于响应式对象上的一个属性,创建一个对应的 ref。这样创建的 ref 与其源属性保持同步:改变源属性的值将更新 ref 的值,反之亦然。
类型
ts// 规范化签名 (3.3+)function toRef( value: T): T extends () => infer R ? Readonly : T extends Ref ? T : Ref// 对象属性签名function toRef( object: T, key: K, defaultValue?: T[K]): ToReftype ToRef = T extends Ref ? T : Ref
示例
规范化签名 (3.3+):
js// 按原样返回现有的 reftoRef(existingRef)// 创建一个只读的 ref,当访问 .value 时会调用此 getter 函数toRef(() => props.foo)// 从非函数的值中创建普通的 ref// 等同于 ref(1)toRef(1)
对象属性签名:
jsconst state = reactive({ foo: 1, bar: 2})// 双向 ref,会与源属性同步const fooRef = toRef(state, 'foo')// 更改该 ref 会更新源属性fooRef.value++console.log(state.foo) // 2// 更改源属性也会更新该 refstate.foo++console.log(fooRef.value) // 3
请注意,这不同于:
jsconst fooRef = ref(state.foo)
上面这个 ref 不会和
state.foo
保持同步,因为这个ref()
接收到的是一个纯数值。toRef()
这个函数在你想把一个 prop 的 ref 传递给一个组合式函数时会很有用:vueimport { toRef } from 'vue'const props = defineProps(/* ... */)// 将 `props.foo` 转换为 ref,然后传入// 一个组合式函数useSomeFeature(toRef(props, 'foo'))// getter 语法——推荐在 3.3+ 版本使用useSomeFeature(toRef(() => props.foo))
当
toRef
与组件 props 结合使用时,关于禁止对 props 做出更改的限制依然有效。尝试将新的值传递给 ref 等效于尝试直接更改 props,这是不允许的。在这种场景下,你可能可以考虑使用带有get
和set
的computed
替代。详情请见在组件上使用v-model
指南。当使用对象属性签名时,即使源属性当前不存在,
toRef()
也会返回一个可用的 ref。这让它在处理可选 props 的时候格外实用,相比之下toRefs
就不会为可选 props 创建对应的 refs。
toValue() {#tovalue}"">
将值、refs 或 getters 规范化为值。这与 unref() 类似,不同的是此函数也会规范化 getter 函数。如果参数是一个 getter,它将会被调用并且返回它的返回值。
这可以在组合式函数中使用,用来规范化一个可以是值、ref 或 getter 的参数。
类型
tsfunction toValue(source: T | Ref | (() => T)): T
示例
jstoValue(1) // --> 1toValue(ref(1)) // --> 1toValue(() => 1) // --> 1
在组合式函数中规范化参数:
tsimport type { MaybeRefOrGetter } from 'vue'function useFeature(id: MaybeRefOrGetter) { watch(() => toValue(id), id => { // 处理 id 变更 })}// 这个组合式函数支持以下的任意形式:useFeature(1)useFeature(ref(1))useFeature(() => 1)
toRefs()
将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef()
创建的。
类型
tsfunction toRefs( object: T): { [K in keyof T]: ToRef}type ToRef = T extends Ref ? T : Ref
示例
jsconst state = reactive({ foo: 1, bar: 2})const stateAsRefs = toRefs(state)/*stateAsRefs 的类型:{ foo: Ref, bar: Ref}*/// 这个 ref 和源属性已经“链接上了”state.foo++console.log(stateAsRefs.foo.value) // 2stateAsRefs.foo.value++console.log(state.foo) // 3
当从组合式函数中返回响应式对象时,
toRefs
相当有用。使用它,消费者组件可以解构/展开返回的对象而不会失去响应性:jsfunction useFeatureX() { const state = reactive({ foo: 1, bar: 2 }) // ...基于状态的操作逻辑 // 在返回时都转为 ref return toRefs(state)}// 可以解构而不会失去响应性const { foo, bar } = useFeatureX()
toRefs
在调用时只会为源对象上可以枚举的属性创建 ref。如果要为可能还不存在的属性创建 ref,请改用toRef
。
isProxy()
检查一个对象是否是由 reactive()
、readonly()
、shallowReactive()
或 shallowReadonly()
创建的代理。
类型
tsfunction isProxy(value: unknown): boolean
isReactive()
检查一个对象是否是由 reactive()
或 shallowReactive()
创建的代理。
类型
tsfunction isReactive(value: unknown): boolean
isReadonly()
检查传入的值是否为只读对象。只读对象的属性可以更改,但他们不能通过传入的对象直接赋值。
通过 readonly()
和 shallowReadonly()
创建的代理都是只读的,因为他们是没有 set
函数的 computed()
ref。
类型
tsfunction isReadonly(value: unknown): boolean
鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!