1. 程式人生 > 其它 >Vue3.0文件學習心得--響應式核心

Vue3.0文件學習心得--響應式核心

1.ref():接受一個內部值,返回一個響應式的、可更改的 ref 物件.此物件只有一個指向其內部值的屬性 .value

使用例項:

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

使用注意項:

如果將一個物件賦值給 ref,那麼這個物件將通過 reactive() 轉為具有深層次響應式的物件。這也意味著如果物件中包含了巢狀的 ref,它們將被深層地解包。若要避免這種深層次的轉換,請使用 shallowRef() 來替代。

2.computed():2種使用方法:(1)建立一個只讀的ref物件,不可以對其進行計算操作(2)通過get和set函式,建立一個可寫的計算屬性ref,

使用例項:

(1)const count = ref(1)  const plusOne = computed(() => count.value + 1)  console.log(plusOne.value) // 2   plusOne.value++ // 錯誤

(2)

const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: (val) => {
    count.value = val - 1
  }
})
plusOne.value = 1  //當對computed物件進行賦值時觸發set操作,從而對count進行操作
console.log(count.value) // 0

3.reactive():  返回一個物件的響應式代理。

(1)響應式轉換是“深層”的:它會影響到所有巢狀的屬性。一個響應式物件也將深層地解包任何 ref 屬性,同時保持響應性。

const count = ref(1)
const obj = reactive({ count })

// ref 會被解包
console.log(obj.count === count.value) // true

// 會更新 `obj.count`
count.value++
console.log(count.value) // 2
console.log(obj.count) // 2   代理響應式,不需要通過value去取值

// 也會更新 `count` ref
obj.count++
console.log(obj.count) // 3
console.log(count.value) // 3
const count = ref(1)
const obj = reactive({})

obj.count = count  //當一個ref賦值給reactive時自動解包

console.log(obj.count) // 1
console.log(obj.count === count.value) // true

(2)當訪問到某個響應式陣列或 Map 這樣的原生集合型別中的 ref 元素時,不會執行 ref 的解包。

const books = reactive([ref('Vue 3 Guide')])
// 這裡需要 .value
console.log(books[0].value)

const map = reactive(new Map([['count', ref(0)]]))
// 這裡需要 .value
console.log(map.get('count').value)

(3) 若要避免深層響應式轉換,只想保留對這個物件頂層次訪問的響應性,請使用 shallowReactive() 作替代。返回的物件以及其中巢狀的物件都會通過 ES Proxy 包裹,因此不等於源物件,建議只使用響應式代理,避免使用原始物件。

4.readonly():接受一個物件 (不論是響應式還是普通的) 或是一個 ref,返回一個原值的只讀代理。

(1)只讀代理是深層的:對任何巢狀屬性的訪問都將是隻讀的。它的 ref 解包行為與 reactive() 相同,但解包得到的值是隻讀的。

const original = reactive({ count: 0 })

const copy = readonly(original)

watchEffect(() => {
  // 用來做響應性追蹤
  console.log(copy.count)
})

// 更改源屬性會觸發其依賴的偵聽器
original.count++   

// 更改該只讀副本將會失敗,並會得到一個警告,但是值會做響應式更改
copy.count++ // warning!

(2)要避免深層級的轉換行為,請使用 shallowReadonly() 作替代。

5.watchEffect():立即執行一個函式,同時響應式地追蹤其依賴,並在依賴更改時重新執行。

 (1):第一個引數就是要執行的副作用函式。
const count = ref(0)

watchEffect(() => console.log(count.value))
// -> 輸出 0  立即執行!

count.value++
// -> 輸出 1

(2)第一個引數副作用函式的引數也是一個函式,用來註冊清理回撥。清理回撥會在該副作用下一次執行前被呼叫,可以用來清理無效的副作用,例如等待中的非同步請求 (參見下面的示例)。

watchEffect(async (onCleanup) => {
  const { response, cancel } = doAsyncWork(id.value)
  // `cancel` 會在 `id` 更改時呼叫
  // 以便取消之前
  // 未完成的請求
  onCleanup(cancel)
  data.value = await response
})

(3)第二個引數是一個可選的選項,可以用來調整副作用的重新整理時機或除錯副作用的依賴。

預設情況下,偵聽器將在元件渲染之前執行。設定 flush: 'post' 將會使偵聽器延遲到元件渲染之後再執行。詳見回撥的觸發時機。在某些特殊情況下 (例如要使快取失效),可能有必要在響應式依賴發生改變時立即觸發偵聽器。這可以通過設定 flush: 'sync' 來實現。然而,該設定應謹慎使用,因為如果有多個屬性同時更新,這將導致一些效能和資料一致性的問題。

watchEffect(() => {}, {
  flush: 'post',
  onTrack(e) {
    debugger
  },
  onTrigger(e) {
    debugger
  }
})

(4)返回值是一個用來停止該副作用的函式

const stop = watchEffect(() => {})

// 當不再需要此偵聽器時:
stop()