Vue 3.0 響應(yīng)性基礎(chǔ) API

2021-07-16 11:27 更新

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

#reactive

返回對(duì)象的響應(yīng)式副本

  1. const obj = reactive({ count: 0 })

響應(yīng)式轉(zhuǎn)換是“深層”的——它影響所有嵌套 property。在基于 ES2015 Proxy 的實(shí)現(xiàn)中,返回的代理是等于原始對(duì)象。建議只使用響應(yīng)式代理,避免依賴原始對(duì)象。

類型聲明:

  1. function reactive<T extends object>(target: T): UnwrapNestedRefs<T>

#readonly

獲取一個(gè)對(duì)象 (響應(yīng)式或純對(duì)象) 或 ref 并返回原始代理的只讀代理。只讀代理是深層的:訪問的任何嵌套 property 也是只讀的。

  1. const original = reactive({ count: 0 })
  2. const copy = readonly(original)
  3. watchEffect(() => {
  4. // 適用于響應(yīng)性追蹤
  5. console.log(copy.count)
  6. })
  7. // 變更original 會(huì)觸發(fā)偵聽器依賴副本
  8. original.count++
  9. // 變更副本將失敗并導(dǎo)致警告
  10. copy.count++ // 警告!

#isProxy

檢查對(duì)象是 reactive 還是 readonly創(chuàng)建的代理

#isReactive

檢查對(duì)象是否是 reactive創(chuàng)建的響應(yīng)式 proxy。

  1. import { reactive, isReactive } from 'vue'
  2. export default {
  3. setup() {
  4. const state = reactive({
  5. name: 'John'
  6. })
  7. console.log(isReactive(state)) // -> true
  8. }
  9. }

如果 proxy 是 readonly 創(chuàng)建的,但還包裝了由 reactive 創(chuàng)建的另一個(gè) proxy,它也會(huì)返回 true。

  1. import { reactive, isReactive, readonly } from 'vue'
  2. export default {
  3. setup() {
  4. const state = reactive({
  5. name: 'John'
  6. })
  7. // 從普通對(duì)象創(chuàng)建的只讀代理
  8. const plain = readonly({
  9. name: 'Mary'
  10. })
  11. console.log(isReactive(plain)) // -> false
  12. // 從響應(yīng)式代理創(chuàng)建的只讀代理
  13. const stateCopy = readonly(state)
  14. console.log(isReactive(stateCopy)) // -> true
  15. }
  16. }

#isReadonly

檢查對(duì)象是否是由readonly創(chuàng)建的只讀代理。

#toRaw

返回 reactivereadonly 代理的原始對(duì)象。這是一個(gè)轉(zhuǎn)義口,可用于臨時(shí)讀取而不會(huì)引起代理訪問/跟蹤開銷,也可用于寫入而不會(huì)觸發(fā)更改。不建議保留對(duì)原始對(duì)象的持久引用。請(qǐng)謹(jǐn)慎使用。

  1. const foo = {}
  2. const reactiveFoo = reactive(foo)
  3. console.log(toRaw(reactiveFoo) === foo) // true

#markRaw

標(biāo)記一個(gè)對(duì)象,使其永遠(yuǎn)不會(huì)轉(zhuǎn)換為代理。返回對(duì)象本身。

  1. const foo = markRaw({})
  2. console.log(isReactive(reactive(foo))) // false
  3. // 嵌套在其他響應(yīng)式對(duì)象中時(shí)也可以使用
  4. const bar = reactive({ foo })
  5. console.log(isReactive(bar.foo)) // false

WARNING

下方的 markRaw 和 shallowXXX API 使你可以有選擇地選擇退出默認(rèn)的深度響應(yīng)式/只讀轉(zhuǎn)換,并將原始的,非代理的對(duì)象嵌入狀態(tài)圖中。它們可以在各種情況下使用:

  • 有些值不應(yīng)被設(shè)置為響應(yīng)式的,例如復(fù)雜的第三方類實(shí)例或 Vue 組件對(duì)象。
  • 當(dāng)渲染具有不可變數(shù)據(jù)源的大列表時(shí),跳過代理轉(zhuǎn)換可以提高性能。

它們被認(rèn)為是高階的,因?yàn)樵歼x擇退出僅在根級(jí)別,因此,如果將嵌套的、未標(biāo)記的原始對(duì)象設(shè)置為響應(yīng)式對(duì)象,然后再次訪問它,則可以得到代理版本。這可能會(huì)導(dǎo)致本源危害——即執(zhí)行依賴于對(duì)象本身但同時(shí)使用同一對(duì)象的原始版本和代理版本的操作:

  1. const foo = markRaw({
  2. nested: {}
  3. })
  4. const bar = reactive({
  5. // 雖然 `foo` 被標(biāo)記為原始,foo.nested 不是。
  6. nested: foo.nested
  7. })
  8. console.log(foo.nested === bar.nested) // false

本源危害通常很少見。然而,為了在安全地避免本源危害的同時(shí)正確地使用這些 API,需要對(duì)響應(yīng)性系統(tǒng)的工作原理有一個(gè)堅(jiān)實(shí)的理解。

#shallowReactive

創(chuàng)建一個(gè)響應(yīng)式代理,該代理跟蹤其自身 property 的響應(yīng)性,但不執(zhí)行嵌套對(duì)象的深度響應(yīng)式轉(zhuǎn)換 (暴露原始值)。

  1. const state = shallowReactive({
  2. foo: 1,
  3. nested: {
  4. bar: 2
  5. }
  6. })
  7. // 改變狀態(tài)本身的性質(zhì)是響應(yīng)式的
  8. state.foo++
  9. // ...但是不轉(zhuǎn)換嵌套對(duì)象
  10. isReactive(state.nested) // false
  11. state.nested.bar++ // 非響應(yīng)式

#shallowReadonly

創(chuàng)建一個(gè)代理,使其自身的 property 為只讀,但不執(zhí)行嵌套對(duì)象的深度只讀轉(zhuǎn)換 (暴露原始值)。

  1. const state = shallowReadonly({
  2. foo: 1,
  3. nested: {
  4. bar: 2
  5. }
  6. })
  7. // 改變狀態(tài)本身的property將失敗
  8. state.foo++
  9. // ...但適用于嵌套對(duì)象
  10. isReadonly(state.nested) // false
  11. state.nested.bar++ // 適用
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)