亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

vue3中ref和reactive的區(qū)別舉例詳解

 更新時間:2025年06月02日 10:48:19   作者:Hopebearer_  
ref和reactive是Vue3中構(gòu)建響應(yīng)式數(shù)據(jù)的兩大核心 API,雖然它們在使用上相似,但底層機(jī)制和適用場景有明顯不同,這篇文章主要介紹了vue3中ref和reactive區(qū)別的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、核心機(jī)制對比

特性refreactive
包裝對象RefImpl類實(shí)現(xiàn)Proxy代理對象
響應(yīng)式原理通過 .value 的 getter/setter 攔截深度代理對象的屬性訪問
數(shù)據(jù)類型支持任意類型(推薦基本類型)僅對象/數(shù)組/集合類型
深層響應(yīng)式自動展開(對象會轉(zhuǎn)為 reactive)默認(rèn)深層響應(yīng)
模板自動解包支持(頂層屬性自動解包)不支持(需保持對象引用)
TS類型推斷Ref 類型包裹原始類型推斷

二、底層實(shí)現(xiàn)剖析

1. reactive簡單實(shí)現(xiàn)

const reactive = (target) => {
  return new Proxy(target, {
    get(target, key) {
      // 依賴收集
      track(target, key)
      return Reflect.get(target, key)
    },
    set(target, key, value, receiver) {
      const oldValue = target[key]
      const result = Reflect.set(target, key, value, receiver)
      if (oldValue !== value) {
        // 觸發(fā)更新
        trigger(target, key)
      }
      return result
    }
    // 其他攔截操作...
  })
}
  • 依賴收集(Track):
    • 通過 track 函數(shù)將當(dāng)前正在執(zhí)行的副作用(effect)與目標(biāo)對象的屬性關(guān)聯(lián)。
    • 使用 WeakMap 存儲依賴關(guān)系,結(jié)構(gòu)為:
targetMap = WeakMap({
  target: Map({
    key: Set(effect1, effect2, ...)
  })
});
  • 觸發(fā)更新(Trigger):
    • 當(dāng)屬性變化時,通過 trigger 函數(shù)找到所有關(guān)聯(lián)的副作用并執(zhí)行。

2. ref 實(shí)現(xiàn)原理

class RefImpl {
  constructor(value) {
    this._value = isObject(value) ? reactive(value) : value;
    this.dep = new Set(); // 依賴集合
  }

  get value() {
    track(this.dep); // 依賴收集
    return this._value;
  }

  set value(newVal) {
    if (this._value !== newVal) {
      this._value = isObject(newVal) ? reactive(newVal) : newVal;
      trigger(this.dep); // 觸發(fā)更新
    }
  }
}

const ref = (value) => new RefImpl(value);
  • 依賴收集與觸發(fā)更新:
    • 每個 ref 實(shí)例內(nèi)部維護(hù)一個 dep 集合(類似 reactive 的依賴管理)。
    • 當(dāng)通過 .value 訪問時,觸發(fā) track;修改時觸發(fā) trigger。
  • 關(guān)鍵設(shè)計(jì):
    • 值類型包裝: 通過 .value 訪問值,解決基本類型無法被 Proxy 直接代理的問題。
    • 自動解包: 在模板中使用 ref 時,Vue 會自動解包(無需寫 .value)。

三、實(shí)戰(zhàn)場景對比

1. 基本類型處理

// 正確用法
const count = ref(0) // ? 自動類型推斷為 Ref<number>

// 錯誤嘗試
const count = reactive(0) // ? 參數(shù)必須是對象類型

2. 對象類型處理

// ref 處理對象(自動解包)
const user = ref({
  name: 'John',
  address: {
    city: 'New York'
  }
})

// 等效于 reactive 寫法
const user = reactive({
  name: 'John',
  address: reactive({
    city: 'New York'
  })
})

// 訪問方式對比
console.log(user.value.name) // ref 需要 .value
console.log(user.name)        // reactive 直接訪問

3. 數(shù)組處理

// ref 數(shù)組
const listRef = ref([1, 2, 3])
listRef.value.push(4) // ? 正確修改方式

// reactive 數(shù)組
const listReactive = reactive([1, 2, 3])
listReactive.push(4) // ? 直接操作

四、高級特性差異

1. 響應(yīng)式丟失問題

// reactive 的解構(gòu)問題
const state = reactive({ count: 0 })
const { count } = state // ? 失去響應(yīng)性

// ref 的 解構(gòu)
const countRef = ref(0)
const count = countRef // ? 仍需通過 .value 訪問

// 正確解構(gòu)方式(reactive)
const state = reactive({ count: 0 })
const countRef = toRef(state, 'count') // ? 保持響應(yīng)

2. 類型替換場景

// ref 允許整體替換
const data = ref({ items: [] })
data.value = fetchData() // ? 響應(yīng)式更新

// reactive 需保持引用
const data = reactive({ items: [] })
Object.assign(data, fetchData()) // ? 正確方式
data = fetchData() ? 破壞響應(yīng)性

五、性能對比分析

操作ref(基本類型)reactive(對象)差異原因
創(chuàng)建速度★★★★☆★★★☆☆Proxy初始化成本較高
屬性訪問★★★★☆★★★☆☆Proxy攔截帶來額外開銷
深層監(jiān)聽★☆☆☆☆★★★★★Proxy自動深度代理
內(nèi)存占用較低較高Proxy對象占用更多內(nèi)存

六、最佳實(shí)踐

1. 組合式函數(shù)規(guī)范

// 推薦返回 ref 保持靈活性
function useCounter(initial = 0) {
  const count = ref(initial)
  return { count }
}

// 復(fù)雜狀態(tài)使用 reactive + toRefs
function useUser() {
  const state = reactive({
    name: '',
    age: ''
  })
  return { ...toRefs(state) }
}

2. 表單處理策略

// 復(fù)雜表單使用 reactive
const form = reactive({
  username: '',
  password: '',
  preferences: {
    theme: 'light',
    notifications: true
  }
})

// 單個表單字段使用 ref
const searchQuery = ref('')

七、特殊場景處理

1. DOM 引用

獲取元素對象或者組件對象只能使用 ref ,reactive無法處理 DOM 引用

<script setup>

const inputRef = ref(null)
</script>

<templete>
  <div ref="inputRef"></div>
</templete>

2. 第三方庫集成

// 需要保持引用的場景
const chartInstance = ref(null)

// 響應(yīng)式配置對象
const options = reacitve({
  title: { text: '熱銷' },
  series: [ ... ]
})

八、總結(jié)選擇策略

1. 優(yōu)先使用 ref 的場景

  • 基本類型值(string/number/boolean)
  • 需要模板自動解包
  • 可能被整體替換的對象
  • 需要傳遞給composable函數(shù)的參數(shù)

2. 優(yōu)先使用 reactive 的場景

  • 復(fù)雜嵌套對象
  • 需要深度響應(yīng)式監(jiān)聽
  • 表單/配置對象等結(jié)構(gòu)化數(shù)據(jù)
  • 需要直接操作集合類型(Map/Set)

3. 混合使用

3.1 reactive 嵌套 ref

const state = reactive({
  count: ref(0), // 基礎(chǔ)類型 ref ,自動解包
  user: ref<User>({ name: '' }) // 對象類型 ref ,自動解包
})
  • 行為特點(diǎn): Vue 會自動解包嵌套在 reactive 中的 ref,訪問時無需 .value
state.count++ // 直接操作數(shù)字(等價于 state.count.value++)
state.user.name = 'john' // 直接操作對象(等價于 state.user.value.name)
  • 適用場景
    • 混合響應(yīng)式類型: 當(dāng) reactive 對象需要包含基礎(chǔ)類型 + 對象類型的混合數(shù)據(jù)時,用 ref 統(tǒng)一包裹,享受自動解包特性。
    • 外部數(shù)據(jù)注入: 當(dāng)某個屬性需要從外部接收 ref 類型時(如組合式函數(shù)返回的 ref),直接將其嵌入 reactive 對象。

3.2 ref 嵌套 reactive

const complexRef = ref({
  data: reactive({ /*...*/ }), // 嵌套 reactive 對象
  status: 'loading'  // 普通屬性(非響應(yīng)式)
})
  • 行為特點(diǎn):
    • 層級訪問: 需要 .value 訪問容器內(nèi)內(nèi)容
    • 響應(yīng)式范圍:
      • complexRef.value.data 是響應(yīng)式對象(reactive 創(chuàng)建)
      • complexRef.value.status 是普通字符串(非響應(yīng)式)
complexRef.value.data.key = "value";  // 直接修改 reactive 對象
complexRef.value.status = "success";  // 修改普通屬性(非響應(yīng)式)
  • 適用場景:
    • 整體替換響應(yīng)式對象 :如果需要完全替換整個響應(yīng)式對象,用 ref 包裹可以保持引用。
    • 組合非響應(yīng)式數(shù)據(jù): 當(dāng)需要混合響應(yīng)式和非響應(yīng)式數(shù)據(jù)時,ref 作為容器更靈活。
complexRef.value = {  // 替換整個對象(觸發(fā)響應(yīng)式更新)
  data: reactive({ /*...*/ }),
  status: 'success'
};

總結(jié) 

到此這篇關(guān)于vue3中ref和reactive的區(qū)別詳解的文章就介紹到這了,更多相關(guān)vue3中ref和reactive區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue中實(shí)現(xiàn)頁面刷新以及局部刷新的方法

    vue中實(shí)現(xiàn)頁面刷新以及局部刷新的方法

    這篇文章主要給大家介紹了關(guān)于vue中實(shí)現(xiàn)頁面刷新以及局部刷新的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-01-01
  • elementui使用el-upload組件如何實(shí)現(xiàn)自定義上傳

    elementui使用el-upload組件如何實(shí)現(xiàn)自定義上傳

    這篇文章主要介紹了elementui使用el-upload組件如何實(shí)現(xiàn)自定義上傳,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Vue3菜單展開和收起實(shí)現(xiàn)

    Vue3菜單展開和收起實(shí)現(xiàn)

    在Vue項(xiàng)目中實(shí)現(xiàn)首頁布局,包括可收放的左側(cè)菜單和主體內(nèi)容區(qū),在store中管理菜單狀態(tài),通過修改isCollapse狀態(tài)控制菜單的展開與收起,在home.vue中編寫左側(cè)菜單欄的代碼和樣式,實(shí)現(xiàn)一個響應(yīng)式的用戶界面
    2024-09-09
  • Vue中如何實(shí)現(xiàn)在線預(yù)覽word文件、excel文件

    Vue中如何實(shí)現(xiàn)在線預(yù)覽word文件、excel文件

    這篇文章主要介紹了Vue中如何實(shí)現(xiàn)在線預(yù)覽word文件、excel文件,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • vue混入mixin的介紹及理解

    vue混入mixin的介紹及理解

    混入(mixin)提供了一種非常靈活的方式,來分發(fā)vue組件中的可復(fù)用功能。一個混入對象可以包含任意組件選項(xiàng)。當(dāng)組件使用混入對象時,所有混入對象的選項(xiàng)將被“混合”進(jìn)入該組件本身的選項(xiàng)
    2022-08-08
  • 詳解關(guān)于Vue2.0路由開啟keep-alive時需要注意的地方

    詳解關(guān)于Vue2.0路由開啟keep-alive時需要注意的地方

    這篇文章主要介紹了關(guān)于Vue2.0路由開啟keep-alive時需要注意的地方,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • elementUI Tree 樹形控件單選實(shí)現(xiàn)示例

    elementUI Tree 樹形控件單選實(shí)現(xiàn)示例

    在ElementUI中樹形控件本身不支持單選功能,本文就來介紹一下如何實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • 簡述vue狀態(tài)管理模式之vuex

    簡述vue狀態(tài)管理模式之vuex

    這篇文章主要介紹了簡述vue狀態(tài)管理模式之vuex,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • 實(shí)例分析編寫vue組件方法

    實(shí)例分析編寫vue組件方法

    在本篇文章中我們給大家總結(jié)了關(guān)于編寫vue組件的方法知識點(diǎn),有此需要的讀者們跟著學(xué)習(xí)下。
    2019-02-02
  • vue插件v-touch的坑及解決(不能上下滑動)

    vue插件v-touch的坑及解決(不能上下滑動)

    這篇文章主要介紹了vue插件v-touch的坑及解決(不能上下滑動),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評論