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

2021-11-03 16:33 更新

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

#ref

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

示例:

  1. const count = ref(0)
  2. console.log(count.value) // 0
  3. count.value++
  4. console.log(count.value) // 1

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

類型聲明:

  1. interface Ref<T> {
  2. value: T
  3. }
  4. function ref<T>(value: T): Ref<T>

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

  1. const foo = ref<string | number>('foo') // foo's type: Ref<string | number>
  2. foo.value = 123 // ok!

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

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

#unref

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

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

#toRef

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

  1. const state = reactive({
  2. foo: 1,
  3. bar: 2
  4. })
  5. const fooRef = toRef(state, 'foo')
  6. fooRef.value++
  7. console.log(state.foo) // 2
  8. state.foo++
  9. console.log(fooRef.value) // 3

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

  1. export default {
  2. setup(props) {
  3. useSomeFeature(toRef(props, 'foo'))
  4. }
  5. }

#toRefs

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

  1. const state = reactive({
  2. foo: 1,
  3. bar: 2
  4. })
  5. const stateAsRefs = toRefs(state)
  6. /*
  7. Type of stateAsRefs:
  8. {
  9. foo: Ref<number>,
  10. bar: Ref<number>
  11. }
  12. */
  13. // ref 和 原始property “鏈接”
  14. state.foo++
  15. console.log(stateAsRefs.foo.value) // 2
  16. stateAsRefs.foo.value++
  17. console.log(state.foo) // 3

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

  1. function useFeatureX() {
  2. const state = reactive({
  3. foo: 1,
  4. bar: 2
  5. })
  6. // 邏輯運行狀態(tài)
  7. // 返回時轉(zhuǎn)換為ref
  8. return toRefs(state)
  9. }
  10. export default {
  11. setup() {
  12. // 可以在不失去響應(yīng)性的情況下破壞結(jié)構(gòu)
  13. const { foo, bar } = useFeatureX()
  14. return {
  15. foo,
  16. bar
  17. }
  18. }
  19. }

#isRef

檢查值是否為ref對象。

#customRef

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

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

  1. <input v-model="text" />

  1. function useDebouncedRef(value, delay = 200) {
  2. let timeout
  3. return customRef((track, trigger) => {
  4. return {
  5. get() {
  6. track()
  7. return value
  8. },
  9. set(newValue) {
  10. clearTimeout(timeout)
  11. timeout = setTimeout(() => {
  12. value = newValue
  13. trigger()
  14. }, delay)
  15. }
  16. }
  17. })
  18. }
  19. export default {
  20. setup() {
  21. return {
  22. text: useDebouncedRef('hello')
  23. }
  24. }
  25. }

Typing:

  1. function customRef<T>(factory: CustomRefFactory<T>): Ref<T>
  2. type CustomRefFactory<T> = (
  3. track: () => void,
  4. trigger: () => void
  5. ) => {
  6. get: () => T
  7. set: (value: T) => void
  8. }

#shallowRef

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

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

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

#triggerRef

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

  1. const shallow = shallowRef({
  2. greet: 'Hello, world'
  3. })
  4. // 第一次運行時記錄一次 "Hello, world"
  5. watchEffect(() => {
  6. console.log(shallow.value.greet)
  7. })
  8. // 這不會觸發(fā)作用,因為 ref 很淺層
  9. shallow.value.greet = 'Hello, universe'
  10. // 記錄 "Hello, universe"
  11. triggerRef(shallow)

參考計算和偵聽 - watchEffect

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號