ref 相关

作者: sweetBoy_9126 | 来源:发表于2022-07-17 14:17 被阅读0次

    这里要注意所有提到的响应式,只有你当前的值在页面上用到了,他才会是响应式的,如果只是单独作为数据处理不在页面体验,那就与响应式无关

    1. ref

    创建基本类型的响应式代理数据

    const a = ref(false)
    a.value = true
    

    2. isRef

    用来判断当前值是否是 ref

    const a = 1
    isRef(a) // false
    
    const b = ref(false)
    isRef(b) // true
    

    3. shallowRef

    相比 ref 创建的代理数据 shallowRef 只针对浅层数据响应式,也就是只针对 .value 这一级,也可以理解为只对基本类型的数据做响应式
    使用场景:数据不需要响应式,提升页面性能

    1). 浅层次响应式

    const b = shallowRef(1)
    const handleCLick = () => {
          b.value = 2
       }
    <div>{b.value}</div>
    <div onClick={handleClick}>按钮</div>
    

    上面因为我们的值是基本类型所以和 ref 没区别,当我们点击按钮的时候 页面上变成2

    2). 深层次无响应式

    const b = shallowRef({
          a: 1,
     })
    const handleCLick = () => {
          b.value.a = 2 // 不会更新 ui
          b.value = {a: 2} // 更新 ui
    }
    

    因为我们知道 .value 一层所以我们修改 .value后面的属性值就不会在页面视图上变化,但是数据是变了的

    3). 如果对深层次数据更新的过程中同时有对浅层次数据或者其他可响应式数据进行了更新,那么深层次数据也会在页面ui层更新

    const a = ref(1)
    const b = shallowRef({
          a: 1,
     })
    const handleCLick = () => {
          a.value = 3
          b.value.a = 2
     }
    <div>{a.value} {b.value.a}</div>
    

    上面代码点击按钮a.value更新了视图a.value变成了3,b.value.a 也在视图上变成了2
    原因:因为我们不管是在ref还是 reactive中更新视图主要是通过 set的时候触发一个 triggerRefValue(所有的响应式数据更新最后调的都是这个),把shallowRef 一并更新了

    4. triggerRef

    配合 shallowRef 使用,如果我们想让深层次属性修改后页面视图变化可以使用 triggerRef 强制render

    const handleCLick = () => {
          b.value.a = 2
          triggerRef(b)
     }
    

    5. customRef

    创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track(用来收集依赖) 和 trigger(触发更新) 函数作为参数,并且应该返回一个带有 get 和 set 的对象。

    <input v-model="text" />
    
    function useDebouncedRef(value, delay = 200) {
      let timeout
      return customRef((track, trigger) => {
        return {
          get() {
            track()
            return value
          },
          set(newValue) {
            clearTimeout(timeout)
            timeout = setTimeout(() => {
              value = newValue
              trigger()
            }, delay)
          }
        }
      })
    }
    
    export default {
      setup() {
        return {
          text: useDebouncedRef('hello')
        }
      }
    }
    

    6. unref

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

    const a = ref(1)
    const test = (param: any) => {
          return unref(param)
        }
        const handleCLick = () => {
          console.log(test(a)) // 1
        }
    

    7. toRefs

    用来解构props 属性,如果不用 toRefs 直接用 es6 解构,props 的属性就不是响应式的了,所以需要我们把所有的 props 转成 ref

    import { toRefs } from 'vue'
    
    setup(props) {
      const { title } = toRefs(props)
    
      console.log(title.value)
    }
    

    8. toRef

    针对某个可选的 prop 属性
    如果 title 是可选的 prop,则传入的 props 中可能没有 title 。在这种情况下,toRefs 将不会为 title 创建一个 ref 。你需要使用 toRef 替代它

    import { toRef } from 'vue'
    setup(props) {
      const title = toRef(props, 'title')
      console.log(title.value)
    }
    

    相关文章

      网友评论

        本文标题:ref 相关

        本文链接:https://www.haomeiwen.com/subject/cttkirtx.html