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()