Vue3中的ref和reactive響應(yīng)式原理解析
Vue3系列4--ref和reactive響應(yīng)式
本節(jié)主要介紹了響應(yīng)式變量和對象,以及變量和對象在響應(yīng)式和非響應(yīng)式之間的轉(zhuǎn)換。
1 ref
接受一個(gè)內(nèi)部值并返回一個(gè)響應(yīng)式且可變的 ref 對象。ref 對象僅有一個(gè).value
property,指向該內(nèi)部值。
案例
<template> <div> <button @click="changeMsg">change</button> <div>{{ message }}</div> </div> </template> <script setup lang="ts"> let message: string = "我是message" const changeMsg = () => { message = "change msg" } </script> <style> </style>
我們這樣操作是無法改變message 的值 應(yīng)為message 不是響應(yīng)式的無法被vue 跟蹤要改成ref。響應(yīng)式就是在頁面上實(shí)時(shí)顯示修改的值。
Ref TS對應(yīng)的接口:
interface Ref<T> { value: T } // 對于接口問題,是TS語法,如果不清楚,直接看TS
但是被ref包裹后需要使用value來進(jìn)行賦值。
<template> <div> <button @click="changeMsg">change</button> <div>{{ message }}</div> </div> </template> <script setup lang="ts"> import {ref,Ref} from 'vue' let message:Ref<string> = ref("我是message")let message= ref<string>("我是message") // 第二種方式const changeMsg = () => { message.value = "change msg" } </script> <style> </style>
2 isref判斷是不是一個(gè)ref對象
import { ref, Ref,isRef } from 'vue' let message: Ref<string | number> = ref("我是message") let notRef:number = 123 const changeMsg = () => { message.value = "change msg" console.log(isRef(message)); //true console.log(isRef(notRef)); //false }
3 shallowref創(chuàng)建一個(gè)跟蹤自身.value變化的 ref,但不會(huì)使其值也變成響應(yīng)式的
例子1
修改其屬性是非響應(yīng)式的這樣是不會(huì)改變的
<template> <div> <button @click="changeMsg">change</button> <div>{{ message }}</div> </div> </template> <script setup lang="ts"> import { Ref, shallowRef } from 'vue' type Obj = { name: string } let message: Ref<Obj> = shallowRef({ name: "唐少" }) const changeMsg = () => { message.value.name = '唐少2' } </script> <style> </style>
例子2
這樣是可以被監(jiān)聽到的修改value,必須要修改整個(gè)對象才行
import { Ref, shallowRef } from 'vue' type Obj = { name: string } let message: Ref<Obj> = shallowRef({ name: "唐少" }) const changeMsg = () => { message.value = { name: "唐少2" } }
4 triggerRef
為了解決shallowRef的問題,我們強(qiáng)制更新頁面DOM,這樣也是可以改變值的
<template> <div> <button @click="changeMsg">change</button> <div>{{ message }}</div> </div> </template> <script setup lang="ts"> import { Ref, shallowRef,triggerRef } from 'vue' type Obj = { name: string } let message: Ref<Obj> = shallowRef({ name: "唐少" }) const changeMsg = () => { message.value.name = '唐2' triggerRef(message) } </script> <style> </style>
5 customRef
自定義ref ,customRef 是個(gè)工廠函數(shù)要求我們返回一個(gè)對象 并且實(shí)現(xiàn) get 和 set
<script setup lang="ts"> import { Ref, shallowRef, triggerRef, customRef } from 'vue' function Myref<T>(value: T) { return customRef((track, trigger) => { return { get() { track() return value }, set(newVal: T) { console.log('set'); value = newVal trigger() } } }) } let message = Myref('唐少') const changeMsg = () => { message.value = '唐少2' // triggerRef(message) } </script>
6 reactive用來綁定復(fù)雜的數(shù)據(jù)類型
例如 對象 數(shù)組
reactive源碼約束了我們的類型,類型必須是object,不能綁定普通的類型,會(huì)報(bào)錯(cuò)。你如果用ref去綁定對象 或者數(shù)組等復(fù)雜的數(shù)據(jù)類型 我們看源碼里面其實(shí)也是 去調(diào)用reactive,但使用reactive 去修改值無須.value
reactive 基礎(chǔ)用法
import { reactive } from 'vue' let person = reactive({ name:"唐少" }) person.name = "唐少2"
數(shù)組異步賦值問題
// 這樣賦值頁面是不會(huì)變化的因?yàn)闀?huì)脫離響應(yīng)式<br data-filtered="filtered">let person = reactive<number[]>([]) setTimeout(() => { person = [1, 2, 3] console.log(person); },1000)
解決方案1:push
import { reactive } from 'vue' let person = reactive<number[]>([]) setTimeout(() => { const arr = [1, 2, 3] person.push(...arr) console.log(person); },1000)
解決方案2:包裹一層對象
type Person = { list?:Array<number> } let person = reactive<Person>({ list:[] }) setTimeout(() => { const arr = [1, 2, 3] person.list = arr; console.log(person); },1000)
7 readonly
拷貝一份proxy對象將其設(shè)置為只讀
import { reactive ,readonly} from 'vue' const person = reactive({count:1}) const copy = readonly(person) //person.count++ copy.count++
8 shallowReactive
只能對淺層的數(shù)據(jù) 如果是深層的數(shù)據(jù)只會(huì)改變值 不會(huì)改變視圖
<template> <div> <div>{{ state }}</div> <button @click="change1">test1</button> <button @click="change2">test2</button> </div> </template> <script setup lang="ts"> import { shallowReactive } from 'vue' const obj = { a: 1, first: { b: 2, second: { c: 3 } } } const state = shallowReactive(obj) function change1() { state.a = 7 } function change2() { state.first.b = 8 state.first.second.c = 9 console.log(state); } </script> <style> </style>
9toRef
如果原始對象是非響應(yīng)式的就不會(huì)更新視圖 數(shù)據(jù)是會(huì)變的,如果原始對象是響應(yīng)式的是會(huì)更新視圖并且改變數(shù)據(jù)的
<template> <div> <button @click="change">按鈕</button> {{state}} </div> </template> <script setup lang="ts"> import { reactive, toRef } from 'vue' const obj = { foo: 1, bar: 1 } const state = toRef(obj, 'bar') // bar 轉(zhuǎn)化為響應(yīng)式對象 const change = () => { state.value++ console.log(obj, state); } </script>
10toRefs
可以幫我們批量創(chuàng)建ref對象主要是方便我們解構(gòu)使用
import { reactive, toRefs } from 'vue' const obj = reactive({ foo: 1, bar: 1 }) let { foo, bar } = toRefs(obj) foo.value++ console.log(foo, bar);
11toRaw
將響應(yīng)式對象轉(zhuǎn)化為普通對象
import { reactive, toRaw } from 'vue' const obj = reactive({ foo: 1, bar: 1 }) const state = toRaw(obj) // 響應(yīng)式對象轉(zhuǎn)化為普通對象 const change = () => { console.log(obj, state); }
到此這篇關(guān)于Vue3中的ref和reactive響應(yīng)式的文章就介紹到這了,更多相關(guān)Vue3 ref和reactive響應(yīng)式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3+el-table封裝示例詳解(編輯、刪除、查看詳情按鈕一起封裝)
在Vue3中,利用Element?Plus?UI庫封裝表格組件,實(shí)現(xiàn)編輯、刪除和查看詳情的功能,通過定義tableData和tableDataHeader來管理表格數(shù)據(jù)和表頭,其中tableData通常從后端獲取,而tableHeader可根據(jù)具體需求自定義,感興趣的朋友跟隨小編一起看看吧2024-09-09vue項(xiàng)目實(shí)現(xiàn)文件下載進(jìn)度條功能
這篇文章主要介紹了vue項(xiàng)目實(shí)現(xiàn)文件下載進(jìn)度條功能,本文通過具體實(shí)現(xiàn)代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09VUE渲染后端返回含有script標(biāo)簽的html字符串示例
今天小編就為大家分享 一篇VUE渲染后端返回含有script標(biāo)簽的html字符串示例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10Vue?運(yùn)行高德地圖官方樣例,設(shè)置class無效的解決
這篇文章主要介紹了Vue?運(yùn)行高德地圖官方樣例,設(shè)置class無效的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10Vue項(xiàng)目中定義全局變量的幾種常用方法總結(jié)
在項(xiàng)目中經(jīng)常有些函數(shù)和變量是需要復(fù)用,比如說網(wǎng)站服務(wù)器地址,從后臺(tái)拿到的用戶的登錄token,用戶的地址信息等,這時(shí)候就需要設(shè)置一波全局變量,這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目中定義全局變量的幾種常用方法的相關(guān)資料,需要的朋友可以參考下2023-12-12解決vue2.x中數(shù)據(jù)渲染以及vuex緩存的問題
本篇文章主要介紹了vue2.x中請求之前數(shù)據(jù)顯示以及vuex緩存的問題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07