Vue 3.0 響應(yīng)性API Refs

2021-11-03 16:33 更新

本節(jié)例子中代碼使用的單文件組件語法

#ref

接受一個內(nèi)部值并返回一個響應(yīng)式且可變的 ref 對象。ref 對象具有指向內(nèi)部值的單個 property .value

示例:

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


count.value++
console.log(count.value) // 1

如果將對象分配為 ref 值,則可以通過 reactive 方法使該對象具有高度的響應(yīng)式。

類型聲明:

interface Ref<T> {
  value: T
}


function ref<T>(value: T): Ref<T>

有時我們可能需要為 ref 的內(nèi)部值指定復(fù)雜類型。我們可以通過在調(diào)用 ref 來覆蓋默認(rèn)推斷時傳遞一個泛型參數(shù)來簡潔地做到這一點:

const foo = ref<string | number>('foo') // foo's type: Ref<string | number>


foo.value = 123 // ok!

如果泛型的類型未知,建議將 ref 轉(zhuǎn)換為 Ref<T>

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

#unref

如果參數(shù)為 ref,則返回內(nèi)部值,否則返回參數(shù)本身。這是 val = isRef(val) ? val.value : val。

function useFoo(x: number | Ref<number>) {
  const unwrapped = unref(x) // unwrapped 確?,F(xiàn)在是數(shù)字類型
}

#toRef

可以用來為源響應(yīng)式對象上的 property 性創(chuàng)建一個 ref。然后可以將 ref 傳遞出去,從而保持對其源 property 的響應(yīng)式連接。

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

當(dāng)您要將 prop 的 ref 傳遞給復(fù)合函數(shù)時,toRef 很有用:

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

#toRefs

將響應(yīng)式對象轉(zhuǎn)換為普通對象,其中結(jié)果對象的每個 property 都是指向原始對象相應(yīng) property 的ref。

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


const stateAsRefs = toRefs(state)
/*
Type of 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

當(dāng)從合成函數(shù)返回響應(yīng)式對象時,toRefs 非常有用,這樣消費組件就可以在不丟失響應(yīng)性的情況下對返回的對象進行分解/擴散:

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


  // 邏輯運行狀態(tài)


  // 返回時轉(zhuǎn)換為ref
  return toRefs(state)
}


export default {
  setup() {
    // 可以在不失去響應(yīng)性的情況下破壞結(jié)構(gòu)
    const { foo, bar } = useFeatureX()


    return {
      foo,
      bar
    }
  }
}

#isRef

檢查值是否為ref對象。

#customRef

創(chuàng)建一個自定義的 ref,并對其依賴項跟蹤和更新觸發(fā)進行顯式控制。它需要一個工廠函數(shù),該函數(shù)接收 tracktrigger 函數(shù)作為參數(shù),并應(yīng)返回一個帶有 getset 的對象。

  • 使用 v-model 使用自定義 ref 實現(xiàn) debounce 的示例:

  <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')
      }
    }
  }

Typing:

function customRef<T>(factory: CustomRefFactory<T>): Ref<T>


type CustomRefFactory<T> = (
  track: () => void,
  trigger: () => void
) => {
  get: () => T
  set: (value: T) => void
}

#shallowRef

創(chuàng)建一個 ref,它跟蹤自己的 .value 更改,但不會使其值成為響應(yīng)式的。

const foo = shallowRef({})
// 改變 ref 的值是響應(yīng)式的
foo.value = {}
// 但是這個值不會被轉(zhuǎn)換。
isReactive(foo.value) // false

參考正在將獨立的響應(yīng)式值創(chuàng)建為 refs

#triggerRef

手動執(zhí)行與 shallowRef](#shallowref) 關(guān)聯(lián)的任何效果。

const shallow = shallowRef({
  greet: 'Hello, world'
})


// 第一次運行時記錄一次 "Hello, world"
watchEffect(() => {
  console.log(shallow.value.greet)
})


// 這不會觸發(fā)作用,因為 ref 很淺層
shallow.value.greet = 'Hello, universe'


// 記錄 "Hello, universe"
triggerRef(shallow)

參考計算和偵聽 - watchEffect

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號