国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Vue3 中應(yīng)該使用 Ref 還是 Reactive?

這篇具有很好參考價(jià)值的文章主要介紹了Vue3 中應(yīng)該使用 Ref 還是 Reactive?。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

為什么要使用 ref?

你可能會好奇:為什么我們需要使用帶有?.value?的 ref,而不是普通的變量?為了解釋這一點(diǎn),我們需要簡單地討論一下 Vue 的響應(yīng)式系統(tǒng)是如何工作的。

當(dāng)你在模板中使用了一個 ref,然后改變了這個 ref 的值時(shí),Vue 會自動檢測到這個變化,并且相應(yīng)地更新 DOM。這是通過一個基于依賴追蹤的響應(yīng)式系統(tǒng)實(shí)現(xiàn)的。當(dāng)一個組件首次渲染時(shí),Vue 會追蹤在渲染過程中使用的每一個 ref。然后,當(dāng)一個 ref 被修改時(shí),它會觸發(fā)追蹤它的組件的一次重新渲染。

在標(biāo)準(zhǔn)的 JavaScript 中,檢測普通變量的訪問或修改是行不通的。然而,我們可以通過 getter 和 setter 方法來攔截對象屬性的 get 和 set 操作。

該?.value?屬性給予了 Vue 一個機(jī)會來檢測 ref 何時(shí)被訪問或修改。在其內(nèi)部,Vue 在它的 getter 中執(zhí)行追蹤,在它的 setter 中執(zhí)行觸發(fā)。從概念上講,你可以將 ref 看作是一個像這樣的對象:

// 偽代碼,不是真正的實(shí)現(xiàn)
const myRef = {
  _value: 0,
  get value() {
    track()
    return this._value
  },
  set value(newValue) {
    this._value = newValue
    trigger()
  }
}

另一個 ref 的好處是,與普通變量不同,你可以將 ref 傳遞給函數(shù),同時(shí)保留對最新值和響應(yīng)式連接的訪問。當(dāng)將復(fù)雜的邏輯重構(gòu)為可重用的代碼時(shí),這將非常有用。

該響應(yīng)性系統(tǒng)在vue官網(wǎng)深入響應(yīng)式原理章節(jié)中有更詳細(xì)的討論。

深層響應(yīng)性

Ref 可以持有任何類型的值,包括深層嵌套的對象、數(shù)組或者 JavaScript 內(nèi)置的數(shù)據(jù)結(jié)構(gòu),比如?Map。

Ref 會使它的值具有深層響應(yīng)性。這意味著即使改變嵌套對象或數(shù)組時(shí),變化也會被檢測到:

import { ref } from 'vue'

const obj = ref({
  nested: { count: 0 },
  arr: ['foo', 'bar']
})

function mutateDeeply() {
  // 以下都會按照期望工作
  obj.value.nested.count++
  obj.value.arr.push('baz')
}

非原始值將通過?reactive()?轉(zhuǎn)換為響應(yīng)式代理,該函數(shù)將在后面討論。

也可以通過shallow ref來放棄深層響應(yīng)性。對于淺層 ref,只有?.value?的訪問會被追蹤。淺層 ref 可以用于避免對大型數(shù)據(jù)的響應(yīng)性開銷來優(yōu)化性能、或者有外部庫管理其內(nèi)部狀態(tài)的情況。

DOM 更新時(shí)機(jī)?

當(dāng)你修改了響應(yīng)式狀態(tài)時(shí),DOM 會被自動更新。但是需要注意的是,DOM 更新不是同步的。Vue 會在“next tick”更新周期中緩沖所有狀態(tài)的修改,以確保不管你進(jìn)行了多少次狀態(tài)修改,每個組件都只會被更新一次。

要等待 DOM 更新完成后再執(zhí)行額外的代碼,可以使用nextTick()全局 API:

import { nextTick } from 'vue'

async function increment() {
  count.value++
  await nextTick()
  // 現(xiàn)在 DOM 已經(jīng)更新了
}

reactive()

還有另一種聲明響應(yīng)式狀態(tài)的方式,即使用?reactive()?API。與將內(nèi)部值包裝在特殊對象中的 ref 不同,reactive()?將使對象本身具有響應(yīng)性:

import { reactive } from 'vue'

const state = reactive({ count: 0 })

值得注意的是,reactive()?返回的是一個原始對象的?Proxy,它和原始對象是不相等的:

const raw = {}
const proxy = reactive(raw)

// 代理對象和原始對象不是全等的
console.log(proxy === raw) // false

只有代理對象是響應(yīng)式的,更改原始對象不會觸發(fā)更新。因此,使用 Vue 的響應(yīng)式系統(tǒng)的最佳實(shí)踐是?僅使用你聲明對象的代理版本

為保證訪問代理的一致性,對同一個原始對象調(diào)用?reactive()?會總是返回同樣的代理對象,而對一個已存在的代理對象調(diào)用?reactive()?會返回其本身:

// 在同一個對象上調(diào)用 reactive() 會返回相同的代理
console.log(reactive(raw) === proxy) // true

// 在一個代理上調(diào)用 reactive() 會返回它自己
console.log(reactive(proxy) === proxy) // true

這個規(guī)則對嵌套對象也適用。依靠深層響應(yīng)性,響應(yīng)式對象內(nèi)的嵌套對象依然是代理:

const proxy = reactive({})

const raw = {}
proxy.nested = raw

console.log(proxy.nested === raw) // false

reactive()?的局限性

  1. 有限的值類型:它只能用于對象類型 (對象、數(shù)組和如?MapSet?這樣的集合類型)。它不能持有如?stringnumber?或?boolean?這樣的原始類型。

  2. 不能替換整個對象:由于 Vue 的響應(yīng)式跟蹤是通過屬性訪問實(shí)現(xiàn)的,因此我們必須始終保持對響應(yīng)式對象的相同引用。這意味著我們不能輕易地“替換”響應(yīng)式對象,因?yàn)檫@樣的話與第一個引用的響應(yīng)性連接將丟失:

    let state = reactive({ count: 0 })
    
    // 上面的 ({ count: 0 }) 引用將不再被追蹤
    // (響應(yīng)性連接已丟失!)
    state = reactive({ count: 1 })
  3. 對解構(gòu)操作不友好:當(dāng)我們將響應(yīng)式對象的原始類型屬性解構(gòu)為本地變量時(shí),或者將該屬性傳遞給函數(shù)時(shí),我們將丟失響應(yīng)性連接:

    ?
    const state = reactive({ count: 0 })
    
    // 當(dāng)解構(gòu)時(shí),count 已經(jīng)與 state.count 斷開連接
    let { count } = state
    // 不會影響原始的 state
    count++
    
    // 該函數(shù)接收到的是一個普通的數(shù)字
    // 并且無法追蹤 state.count 的變化
    // 我們必須傳入整個對象以保持響應(yīng)性
    callSomeFunction(state.count)

由于這些限制,我們建議使用?ref()?作為聲明響應(yīng)式狀態(tài)的主要 API。

為什么推薦使用ref而不是reactive呢?

  1. 局限性問題:?reactive本身存在一些局限性,可能會在開發(fā)過程中引發(fā)一些問題。這需要額外的注意力和處理,否則可能對開發(fā)造成麻煩。

  2. 數(shù)據(jù)類型限制:?reactive聲明的數(shù)據(jù)類型僅限于對象,而ref則更加靈活,可以容納任何數(shù)據(jù)類型。這使得ref更適合一般的響應(yīng)式狀態(tài)的聲明。

  3. 官方推薦:?官方文檔強(qiáng)烈建議使用ref()作為聲明響應(yīng)式狀態(tài)的首選。這是因?yàn)?code>ref更簡單、更直觀,同時(shí)避免了reactive可能引發(fā)的一些問題。

總的來說:除非有特定的需求需要使用reactive,否則在大多數(shù)情況下更推薦使用ref()

reactive和?ref?對比

reactive ref
? 只支持對象和數(shù)組(引用數(shù)據(jù)類型) ? 支持基本數(shù)據(jù)類型 + 引用數(shù)據(jù)類型
? 在?<script>?和?<template>?中無差別使用 ? 在?<script>?和?<template>?使用方式不同(在?<script>?中要使用?.value
? 重新分配一個新對象會丟失響應(yīng)性 ? 重新分配一個新對象不會失去響應(yīng)
能直接訪問屬性 需要使用?.value?訪問屬性
? 將對象傳入函數(shù)時(shí),失去響應(yīng) ? 傳入函數(shù)時(shí),不會失去響應(yīng)
? 解構(gòu)時(shí)會丟失響應(yīng)性,需使用?toRefs ? 解構(gòu)對象時(shí)會丟失響應(yīng)性,需使用?toRefs

即:

  • ref?用于將基本類型的數(shù)據(jù)和引用數(shù)據(jù)類型(對象)轉(zhuǎn)換為響應(yīng)式數(shù)據(jù),通過?.value?訪問和修改。

  • reactive?用于將對象轉(zhuǎn)換為響應(yīng)式數(shù)據(jù),可以直接訪問和修改屬性,適用于復(fù)雜的嵌套對象和數(shù)組。

01:?reactive?有限的值類型

reactive?只能聲明引用數(shù)據(jù)類型(對象)

let?obj?=?reactive({
??name:?'小明',
??age:?18
})

ref?既能聲明基本數(shù)據(jù)類型,也能聲明對象和數(shù)組

Vue 提供了?ref()?方法,允許我們創(chuàng)建可以使用任何值類型的響應(yīng)式?ref。

//?對象
const?state?=?ref({})
//?數(shù)組
const?state2?=?ref([])

使用?ref,你可以靈活地聲明基本數(shù)據(jù)類型、對象或數(shù)組,而不受像?reactive?那樣只能處理引用數(shù)據(jù)類型的限制。這為開發(fā)提供了更大的靈活性,尤其是在處理不同類型的數(shù)據(jù)時(shí)。

02:?reactive?使用不當(dāng)會失去響應(yīng)

使用?reactive?時(shí),如果不當(dāng)使用,可能導(dǎo)致響應(yīng)性失效,帶來一些困擾。這可能讓開發(fā)者在愉快編碼的同時(shí),突然發(fā)現(xiàn)某些操作失去了響應(yīng)性,不明所以。因此,建議在不了解?reactive?失去響應(yīng)的情況下慎用,而更推薦使用?ref。

1. 賦值給?reactive?一個整個對象或?reactive?對象

賦值一個普通對象
let?state?=?reactive({?count:?0?})
//?這個賦值將導(dǎo)致?state?失去響應(yīng)
state?=?{?count:?1?}
賦值一個?reactive?對象
<template>
??{{?state?}}
</template>????

<script?setup>
const?state?=?reactive({?count:?0?})
//?在?nextTick?異步方法中修改?state?的值
nextTick(()?=>?{
??//?并不會觸發(fā)修改?DOM?,說明失去響應(yīng)了
??state?=?reactive({?count:?11?});
});
</script>

在?nextTick?中給?state?賦值一個?reactive?的響應(yīng)式對象,但是 DOM 并沒有更新。

解決方法:

  1. 不要直接整個對象替換,一個個屬性賦值

let?state?=?reactive({?count:?0?})
//?state?=?{?count:?1?}
state.count?=?1
  1. 使用?Object.assign

let?state?=?reactive({?count:?0?})
//?state?=?{?count:?1?},state?不會失去響應(yīng)
state?=?Object.assign(state,?{?count:?1?})
  1. 使用?ref?定義對象

let?state?=?ref({?count:?0?})
state.value?=?{?count:?1?}

2. 將?reactive?對象的屬性賦值給變量(斷開連接/深拷貝)

這種操作類似于深拷貝,不再共享同一內(nèi)存地址,而是只是字面量的賦值,對該變量的賦值不會影響原來對象的屬性值。

let?state?=?reactive({?count:?0?})
//?賦值給?n,n?和?state.count?不再共享響應(yīng)性連接
let?n?=?state.count
//?不影響原始的?state
n++
console.log(state.count)?//?0

解決方案:

  • 避免將?reactive?對象的屬性賦值給變量。

3. 直接?reactive?對象解構(gòu)時(shí)

直接解構(gòu)會失去響應(yīng)。

let?state?=?reactive({?count:?0?})
//?普通解構(gòu),count?和?state.count?失去了響應(yīng)性連接
let?{?count?}?=?state
count++?//?state.count?值依舊是?0

解決方案:

使用?toRefs?解構(gòu),解構(gòu)后的屬性是?ref?的響應(yīng)式變量。

const?state?=?reactive({?count:?0?})
//?使用?toRefs?解構(gòu),后的屬性為?ref?的響應(yīng)式變量
let?{?count?}?=?toRefs(state)
count.value++?//?state.count?值改變?yōu)?1

建議:ref?一把梭

推薦使用?ref,總結(jié)原因如下:

  1. reactive?有限的值類型:只能聲明引用數(shù)據(jù)類型(對象/數(shù)組)。

  2. reactive?在一些情況下會失去響應(yīng),這可能導(dǎo)致數(shù)據(jù)回顯失去響應(yīng)(數(shù)據(jù)改了,DOM 沒更新)。

???<template>
?????{{?state.a?}}
?????{{?state.b?}}
?????{{?state.c?}}
???</template>
???
???<script>
???let?state?=?reactive({?a:?1,?b:?2,?c:?3?})
???onMounted(()?=>?{
?????//?通過?AJAX?請求獲取的數(shù)據(jù),回顯到?reactive,如果處理不好將導(dǎo)致變量失去響應(yīng)
?????//?回顯失敗,給響應(yīng)式數(shù)據(jù)賦值一個普通對象
?????state?=?{?a:?11,?b:?22,?c:?333?}
?????//?回顯成功,一個個屬性賦值
?????state.a?=?11
?????state.b?=?22
?????state.c?=?33
???})
???</script>

上面這個例子如果是使用?ref?進(jìn)行聲明,直接賦值即可,不需要將屬性拆分一個個賦值。

使用?ref?替代?reactive

???<template>
?????{{?state.a?}}
?????{{?state.b?}}
?????{{?state.c?}}
???</template>
???
???<script>
???let?state?=?ref({?a:?1,?b:?2,?c:?3?})
???onMounted(()?=>?{
?????//?回顯成功
?????state.value?=?{?a:?11,?b:?22,?c:?333?}
???})
???</script>
    • 給響應(yīng)式對象的字面量賦一整個普通對象或?reactive?對象將導(dǎo)致?reactive?聲明的響應(yīng)式數(shù)據(jù)失去響應(yīng)。

  1. ref?適用范圍更廣,可聲明基本數(shù)據(jù)類型和引用數(shù)據(jù)類型。

雖然使用?ref?聲明的變量在讀取和修改時(shí)都需要加?.value?小尾巴,但正因?yàn)橛羞@個小尾巴,我們在 review 代碼的時(shí)候就很清楚知道這是一個?ref?聲明的響應(yīng)式數(shù)據(jù)。

ref?的?.value?好麻煩!

ref?聲明的響應(yīng)式變量攜帶迷人的?.value?小尾巴,讓我們一眼就能確定它是一個響應(yīng)式變量。雖然使用?ref?聲明的變量在讀取和修改時(shí)都需要加?.value?小尾巴,但是正因?yàn)橛羞@個小尾巴,我們在 review 代碼的時(shí)候就很清楚知道這是一個?ref?聲明的響應(yīng)式數(shù)據(jù)。

Volar 插件能自動補(bǔ)全?.value

推薦?ref?一把梭,但是?ref?又得到處?.value,那就交給插件來完成吧!

  • Volar?自動補(bǔ)全?.value(不是默認(rèn)開啟,需要手動開啟)

reactive?重新賦值丟失響應(yīng)是因?yàn)橐玫刂纷兞?,?proxy?代理的對象已經(jīng)不是原來的那個,所以丟失響應(yīng)了。其實(shí)?ref?也是一樣的,當(dāng)把?.value?那一層替換成另外一個有著?.value?的對象也會丟失響應(yīng)。ref?定義的屬性等價(jià)于?reactive({ value: xxx })

另外,說使用?Object.assign?為什么可以更新模板:

Object.assign?解釋是這樣的:如果目標(biāo)對象與源對象具有相同的鍵(屬性名),則目標(biāo)對象中的屬性將被源對象中的屬性覆蓋,后面的源對象的屬性將類似地覆蓋前面的源對象的同名屬性。

那個解決方法里不用重新賦值,直接?Object.assign(state, { count: 1 })?即可,所以只要?proxy?代理的引用地址沒變,就會一直存在響應(yīng)性

?文章來源地址http://www.zghlxwxcb.cn/news/detail-830278.html

到了這里,關(guān)于Vue3 中應(yīng)該使用 Ref 還是 Reactive?的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Vue3為什么推薦使用ref而不是reactive

    Vue3為什么推薦使用ref而不是reactive

    reactive 本身具有很大局限性導(dǎo)致使用過程需要額外注意,如果忽視這些問題將對開發(fā)造成不小的麻煩;ref更像是vue2時(shí)代 option api 的 data 的替代,可以存放任何數(shù)據(jù)類型,而 reactive 聲明的數(shù)據(jù)類型只能是對象; 先拋出結(jié)論,再詳細(xì)說原因:非必要不用 reactive ! (官方文檔也有對應(yīng)的推薦

    2024年02月07日
    瀏覽(26)
  • 【vue3.0中ref與reactive的區(qū)別及使用】

    ref與reactive都是Vue3.0中新增的API,用于響應(yīng)式數(shù)據(jù)的處理。 ref是一個函數(shù),可以用于將一個普通的數(shù)據(jù)類型轉(zhuǎn)換成響應(yīng)式數(shù)據(jù)。ref返回一個包含value屬性的對象,通過修改value屬性的值,可以觸發(fā)組件更新。 使用方式如下: reactive是一個函數(shù),用于將一個普通的對象轉(zhuǎn)換成響

    2024年02月11日
    瀏覽(21)
  • Vue3中的`ref`和`reactive使用中遇到的一些坑

    以下是一些常見的問題和解決方法: 同時(shí)使用 ref 和 reactive :在Vue3中, ref 和 reactive 是兩種不同的數(shù)據(jù)響應(yīng)方式。 ref 用于包裝基本類型數(shù)據(jù),而 reactive 用于包裝對象。如果在同一個變量上同時(shí)使用 ref 和 reactive ,可能會導(dǎo)致數(shù)據(jù)的不一致性和混亂。因此,應(yīng)該根據(jù)變量的

    2024年01月24日
    瀏覽(48)
  • vue3 #ref #reactive

    一、ref 函數(shù)將簡單類型的數(shù)據(jù)包裝為響應(yīng)式數(shù)據(jù) import { ref?} from \\\'vue\\\'? const count = ref(10) 一、reactive函數(shù)將復(fù)雜類型的數(shù)據(jù)包裝為響應(yīng)式數(shù)據(jù) import { reactive} from \\\'vue\\\'? const obj= reactive({ ? ? name : \\\'zs\\\', ? ? age : 18 })

    2024年02月22日
    瀏覽(24)
  • Vue3 ref與reactive

    Vue3 ref與reactive

    在當(dāng)今Web開發(fā)領(lǐng)域中,構(gòu)建交互性強(qiáng)、可復(fù)用且易于維護(hù)的用戶界面是至關(guān)重要的。而Vue.js作為一款現(xiàn)代化且流行的JavaScript框架,正是為了滿足這些需求而誕生。它采用了MVVM架構(gòu)模式,并通過數(shù)據(jù)驅(qū)動和組件化的方式,使我們能夠更輕松地構(gòu)建出優(yōu)雅而高效的Web應(yīng)用程序。

    2024年01月24日
    瀏覽(19)
  • vue3 ref 和 reactive 區(qū)別

    最近學(xué)習(xí)cloud項(xiàng)目,前端使用到 vue3 + ts 等技術(shù),在寫需求過程中遇到 響應(yīng)式數(shù)據(jù)問題,經(jīng)百度查找相關(guān)筆記 ,在此記錄一下,在實(shí)戰(zhàn)中成長吧。 出現(xiàn)的問題 : 定義一個默認(rèn)數(shù)組并且 for 循環(huán)展示,后端返回?cái)?shù)據(jù)并且賦值到數(shù)組中,但是展示的值并不會修改 原因 : 在 js 中

    2023年04月09日
    瀏覽(61)
  • Vue3的ref和reactive

    目錄 1、ref的基本使用 2、reactive的基本使用 3、ref操作dom 4、ref與reactive的異同 ref創(chuàng)建數(shù)據(jù)可以是基本類型也可以是引用類型 ref函數(shù)創(chuàng)建響應(yīng)式數(shù)據(jù),返回值是一個對象 模版中使用ref數(shù)據(jù),省略.value,js代碼中不能省略 獲取ref創(chuàng)建數(shù)據(jù)的值要加上.value ? reactive創(chuàng)建響應(yīng)式 reac

    2024年01月24日
    瀏覽(28)
  • vue3 自動引入 ref reactive...

    npm i unplugin-auto-import -D vite.config.js Q?: typescript 報(bào)錯:‘reactive’ is not defined. A :?TS 未識別到 vue api,沒有相應(yīng)的模塊聲明文件,?在 vite 中配置并生成 auto-imports.d.ts ,并在 tsconfig.json 中引入 vite.config.js tsconfig.json Q:?eslint 無法識別報(bào)錯 error ‘reactive’ is not defined no-undef A:?未配置

    2024年01月25日
    瀏覽(28)
  • 談?wù)刅ue3中的ref和reactive

    談?wù)刅ue3中的ref和reactive

    一、是什么? ref和reactive是Vue3中用來實(shí)現(xiàn) 數(shù)據(jù)響應(yīng)式的API 一般情況下, ref 定義基本數(shù)據(jù)類型, reactive 定義引用數(shù)據(jù)類型 (我喜歡用它來定義對象,不用它定義數(shù)組,原因后面講) 我理解的 ref本質(zhì)上是reactive的再封裝 二、先聊reactive reactive定義引用數(shù)據(jù)類型(以對象和數(shù)

    2023年04月21日
    瀏覽(29)
  • 前端Vue篇之Vue3響應(yīng)式:Ref和Reactive

    在Vue3中,響應(yīng)式編程是非常重要的概念,其中 Ref 和 Reactive 是兩個關(guān)鍵的API。 Ref : Ref 用于創(chuàng)建一個響應(yīng)式的基本數(shù)據(jù)類型,比如數(shù)字、字符串等。它將普通的數(shù)據(jù)變成響應(yīng)式數(shù)據(jù),可以監(jiān)聽數(shù)據(jù)的變化。使用 Ref 時(shí),我們可以通過 .value 來訪問和修改數(shù)據(jù)的值。 Reactive :

    2024年04月25日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包