百科狗-知识改变命运!
--

响应式 API:工具函数 ​

是丫丫呀2年前 (2023-11-21)阅读数 47#技术干货
文章标签属性

响应式 API:工具函数 ​

isRef() ​

检查某个值是否为 ref。

  • 类型

    ts
    function isRef(r: Ref | unknown): r is Ref

    请注意,返回值是一个类型判定 (type predicate),这意味着isRef可以被用作类型守卫:

    ts
    let foo: unknown
    if (isRef(foo)) {
      // foo 的类型被收窄为了 Ref
      foo.value
    }

unref() ​

如果参数是 ref,则返回内部值,否则返回参数本身。这是val = isRef(val) ? val.value : val计算的一个语法糖。

  • 类型

    ts
    function unref(ref: T | Ref): T
  • 示例

    ts
    function 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]
    ): ToRef
    
    type ToRef = T extends Ref ? T : Ref
  • 示例

    规范化签名 (3.3+):

    js
    // 按原样返回现有的 ref
    toRef(existingRef)
    
    // 创建一个只读的 ref,当访问 .value 时会调用此 getter 函数
    toRef(() => props.foo)
    
    // 从非函数的值中创建普通的 ref
    // 等同于 ref(1)
    toRef(1)

    对象属性签名:

    响应式 API:工具函数 ​

    js
    const state = reactive({
      foo: 1,
      bar: 2
    })
    
    // 双向 ref,会与源属性同步
    const fooRef = toRef(state, 'foo')
    
    // 更改该 ref 会更新源属性
    fooRef.value++
    console.log(state.foo) // 2
    
    // 更改源属性也会更新该 ref
    state.foo++
    console.log(fooRef.value) // 3

    请注意,这不同于:

    js
    const fooRef = ref(state.foo)

    上面这个 ref不会state.foo保持同步,因为这个ref()接收到的是一个纯数值。

    toRef()这个函数在你想把一个 prop 的 ref 传递给一个组合式函数时会很有用:

    vue
    
    import { 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,这是不允许的。在这种场景下,你可能可以考虑使用带有getsetcomputed替代。详情请见在组件上使用v-model指南。

    当使用对象属性签名时,即使源属性当前不存在,toRef()也会返回一个可用的 ref。这让它在处理可选 props 的时候格外实用,相比之下toRefs就不会为可选 props 创建对应的 refs。

toValue() {#tovalue}"">​

将值、refs 或 getters 规范化为值。这与 unref() 类似,不同的是此函数也会规范化 getter 函数。如果参数是一个 getter,它将会被调用并且返回它的返回值。

这可以在组合式函数中使用,用来规范化一个可以是值、ref 或 getter 的参数。

  • 类型

    ts
    function toValue(source: T | Ref | (() => T)): T
  • 示例

    js
    toValue(1) //       --> 1
    toValue(ref(1)) //  --> 1
    toValue(() => 1) // --> 1

    在组合式函数中规范化参数:

    ts
    import type { MaybeRefOrGetter } from 'vue'
    
    function useFeature(id: MaybeRefOrGetter) {
      watch(() => toValue(id), id => {
        // 处理 id 变更
      })
    }
    
    // 这个组合式函数支持以下的任意形式:
    useFeature(1)
    useFeature(ref(1))
    useFeature(() => 1)

toRefs() ​

将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用toRef()创建的。

  • 类型

    ts
    function toRefs(
      object: T
    ): {
      [K in keyof T]: ToRef
    }
    
    type ToRef = T extends Ref ? T : Ref
  • 示例

    js
    const state = reactive({
      foo: 1,
      bar: 2
    })
    
    const stateAsRefs = toRefs(state)
    /*
    stateAsRefs 的类型:{
      foo: Ref,
      bar: Ref
    }
    */
    
    // 这个 ref 和源属性已经“链接上了”
    state.foo++
    console.log(stateAsRefs.foo.value) // 2
    
    stateAsRefs.foo.value++
    console.log(state.foo) // 3

    当从组合式函数中返回响应式对象时,toRefs相当有用。使用它,消费者组件可以解构/展开返回的对象而不会失去响应性:

    js
    function 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()创建的代理。

  • 类型

    ts
    function isProxy(value: unknown): boolean

isReactive() ​

检查一个对象是否是由reactive()shallowReactive()创建的代理。

  • 类型

    ts
    function isReactive(value: unknown): boolean

isReadonly() ​

检查传入的值是否为只读对象。只读对象的属性可以更改,但他们不能通过传入的对象直接赋值。

通过readonly()shallowReadonly()创建的代理都是只读的,因为他们是没有set函数的computed()ref。

  • 类型

    ts
    function isReadonly(value: unknown): boolean

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)
最新文章