溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Vue3中的ref和reactive響應(yīng)式原理實例分析

發(fā)布時間:2022-08-08 15:38:40 來源:億速云 閱讀:199 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“Vue3中的ref和reactive響應(yīng)式原理實例分析”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Vue3中的ref和reactive響應(yīng)式原理實例分析”吧!

1 ref

接受一個內(nèi)部值并返回一個響應(yīng)式且可變的 ref 對象。ref 對象僅有一個.valueproperty,指向該內(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)式就是在頁面上實時顯示修改的值。

Ref TS對應(yīng)的接口:

interface Ref<T> {
  value: T
} // 對于接口問題,是TS語法,如果不清楚,直接看TS

但是被ref包裹后需要使用value來進行賦值。

<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判斷是不是一個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)建一個跟蹤自身.value變化的 ref,但不會使其值也變成響應(yīng)式的

例子1

修改其屬性是非響應(yīng)式的這樣是不會改變的

<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,必須要修改整個對象才行

import { Ref, shallowRef } from 'vue'
type Obj = {
  name: string
}
let message: Ref<Obj> = shallowRef({
  name: "唐少"
})
  
const changeMsg = () => {
  message.value = { name: "唐少2" }
}

4 triggerRef

為了解決shallowRef的問題,我們強制更新頁面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 是個工廠函數(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,不能綁定普通的類型,會報錯。你如果用ref去綁定對象 或者數(shù)組等復(fù)雜的數(shù)據(jù)類型 我們看源碼里面其實也是 去調(diào)用reactive,但使用reactive 去修改值無須.value

reactive 基礎(chǔ)用法

import { reactive } from 'vue'
let person = reactive({
   name:"唐少"
})
person.name = "唐少2"

數(shù)組異步賦值問題

// 這樣賦值頁面是不會變化的因為會脫離響應(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ù)只會改變值 不會改變視圖

<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)式的就不會更新視圖 數(shù)據(jù)是會變的,如果原始對象是響應(yīng)式的是會更新視圖并且改變數(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);
}

感謝各位的閱讀,以上就是“Vue3中的ref和reactive響應(yīng)式原理實例分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Vue3中的ref和reactive響應(yīng)式原理實例分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI