【vue-6】Vue3 響應式數據聲明:深入理解 ref()

在 Vue3 的 Composition API 中,ref() 是最基礎也是最常用的響應式數據聲明方式之一。它為開發者提供了一種簡單而強大的方式來管理組件狀態。本文將深入探討 ref() 的工作原理、使用場景以及最佳實踐。

1. 什么是 ref()?

ref() 是 Vue3 提供的一個函數,用于創建一個響應式的引用對象。它可以包裝任何類型的值,使其變為響應式數據。

import { ref } from 'vue'const count = ref(0)

2. ref() 的核心特性

2.1 響應式包裝

ref() 接受一個內部值并返回一個響應式的、可變的 ref 對象,該對象只有一個 .value 屬性指向內部值。

const num = ref(10)
console.log(num.value) // 10num.value = 20
console.log(num.value) // 20

2.2 類型保留

ref() 會保留原始值的類型信息,TypeScript 用戶可以獲得完整的類型推斷。

const message = ref('Hello') // Ref<string>
const age = ref(25) // Ref<number>
const user = ref({ name: 'Alice' }) // Ref<{ name: string }>

2.3 模板自動解包

在模板中使用 ref 時,不需要通過 .value 訪問,Vue 會自動解包。

<template><div>{{ count }}</div><!-- 不需要寫成 count.value -->
</template>

3. ref() 的工作原理

3.1 底層實現

ref() 本質上是對 reactive() 的封裝,它創建了一個包含 value 屬性的響應式對象:

function ref(value) {return reactive({ value })
}

3.2 為什么需要 ref()?

你可能會有疑問:既然有 reactive(),為什么還需要 ref()?主要原因有:

  1. 原始值包裝:JavaScript 原始值(string, number, boolean 等)不是對象,無法用 reactive() 直接包裝。
  2. 一致性:在組合函數中返回響應式值時,使用 ref() 可以保持一致性。
  3. 性能考慮:對于簡單值,ref()reactive() 更輕量。

4. ref() 的使用場景

4.1 基本類型數據

const name = ref('Alice')
const age = ref(25)
const isActive = ref(true)

4.2 DOM 元素引用

<template><input ref="inputRef" />
</template><script setup>
import { ref, onMounted } from 'vue'const inputRef = ref(null)onMounted(() => {inputRef.value.focus()
})
</script>

4.3 組合函數返回值

// useCounter.js
import { ref } from 'vue'export function useCounter(initialValue = 0) {const count = ref(initialValue)function increment() {count.value++}return {count,increment}
}

5. ref() 的高級用法

5.1 解構 ref 對象

const user = ref({name: 'Alice',age: 25
})// 解構會失去響應性
const { name, age } = user // ? 錯誤方式// 正確方式:使用 toRefs
import { toRefs } from 'vue'
const { name, age } = toRefs(user.value) // ?

5.2 ref() 與 reactive() 結合

const state = reactive({count: ref(0), // 自動解包user: ref({ name: 'Alice' })
})console.log(state.count) // 0,不需要 .value

5.3 自定義 ref

Vue 提供了 customRef() 用于創建自定義的 ref 實現:

import { customRef } from 'vue'function debouncedRef(value, delay = 200) {let timeoutreturn customRef((track, trigger) => {return {get() {track()return value},set(newValue) {clearTimeout(timeout)timeout = setTimeout(() => {value = newValuetrigger()}, delay)}}})
}const text = debouncedRef('hello')

6. ref() 的注意事項

  1. .value 訪問:在 JavaScript 中必須通過 .value 訪問 ref 的值,但在模板中會自動解包。
  2. 嵌套 ref:避免不必要的嵌套 ref,如 ref(ref(0))
  3. 數組和對象:對于復雜數據結構,reactive() 可能更合適。
  4. 解構問題:直接解構 ref 對象會失去響應性,使用 toRefs 解決。

7. ref() vs reactive()

特性ref()reactive()
創建方式ref(value)reactive(object)
訪問方式需要 .value (JS中)直接訪問
適用類型任意類型對象/數組
模板使用自動解包直接使用
解構需要使用 toRefs需要使用 toRefs

8. 性能考慮

  • ref() 對于簡單值比 reactive() 更輕量
  • 避免在大型數組或復雜對象上使用多個 ref(),考慮使用 reactive()
  • 在組合函數中優先返回 ref() 以保持一致性

9. 最佳實踐

  1. 命名約定:為 ref 對象添加 Ref 后綴,如 inputRef,提高代碼可讀性。
  2. 類型安全:為 ref 提供明確的類型注解(TypeScript)。
  3. 適度使用:簡單數據用 ref(),復雜對象用 reactive()
  4. 組合函數:在可組合函數中始終返回 ref() 以保持一致性。

10. 結語

ref() 作為 Vue3 響應式系統的基石之一,提供了簡單而強大的狀態管理能力。理解其工作原理和適用場景,能夠幫助開發者編寫更高效、更可維護的 Vue 代碼。無論是簡單的計數器還是復雜的業務邏輯,ref() 都能勝任,是 Vue3 開發中不可或缺的工具。

希望本文能幫助你更好地理解和運用 ref(),在你的 Vue 項目中發揮它的最大價值!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/89810.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/89810.shtml
英文地址,請注明出處:http://en.pswp.cn/web/89810.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HTML常用標簽匯總(精簡版)

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>簡單標記</title> </head><body>&…

【.net core】支持通過屬性名稱索引的泛型包裝類

類/// <summary> /// 支持通過屬性名稱索引的泛型包裝類 /// </summary> public class PropertyIndexer<T> : IEnumerable<T> {private T[] _items;private T _instance;private PropertyInfo[] _properties;private bool _caseSensitive;public Prope…

【機器學習|學習筆記】詳解支持向量機(Support Vector Machine,SVM)為何要引入核函數?為何對缺失數據敏感?

【機器學習|學習筆記】詳解支持向量機(Support Vector Machine,SVM)為何要引入核函數?為何對缺失數據敏感? 【機器學習|學習筆記】詳解支持向量機(Support Vector Machine,SVM)為何要引入核函數?為何對缺失數據敏感? 文章目錄 【機器學習|學習筆記】詳解支持向量機(…

Bicep入門篇

前言 Azure Bicep 是 ARM 模板的最新版本,旨在解決開發人員在將資源部署到 Azure 時遇到的一些問題。它是一款開源工具,實際上是一種領域特定語言 (DSL),它提供了一種聲明式編寫基礎架構的方法,該基礎架構描述了虛擬機、Web 應用和網絡接口等云資源的拓撲結構。它還鼓勵在…

命名實體識別15年研究全景:從規則到機器學習的演進(1991-2006)

本文精讀NRC Canada與NYU聯合發表的經典綜述《A survey of named entity recognition and classification》&#xff0c;解析NERC技術演進脈絡與核心方法論 一、為什么命名實體識別&#xff08;NER&#xff09;如此重要&#xff1f; 命名實體識別&#xff08;Named Entity Rec…

eNSP綜合實驗(DNCP、NAT、TELET、HTTP、DNS)

1搭建實驗拓撲2實驗目的學習掌握eNSP中的命令3實驗步驟3.1配置連接PC和客戶端的交換機(僅以右側為例)[Huawei]vlan batch 10 20 #創建vlan Info: This operation may take a few seconds. Please wait for a moment...done. [Huawei]un in en [Huawei]interface e0/0/2 [Huawei…

無人系統與安防監控中的超低延遲直播技術應用:基于大牛直播SDK的實戰分享

技術背景 在 無人機、機器人 以及 智能安防 等高要求行業&#xff0c;高清視頻的超低延遲傳輸 正在成為影響系統性能與業務決策的重要因素。無論是工業生產線的遠程巡檢、突發事件的應急響應&#xff0c;還是高風險環境下的智能監控與遠程控制&#xff0c;視頻鏈路的傳輸延遲都…

go語言學習之包

概念&#xff1a;在Go 語言中&#xff0c;包由一個或多個保存在同一目錄的源碼文件組成&#xff0c;包名宇目錄名無關&#xff0c;但是通常大家習慣包名和目錄名保持一致&#xff0c;同一目錄的源碼文件必須使用相同的包名。包的用途類似于其他語言的命名空間&#xff0c;可以限…

pytorch學習筆記(五)-- 計算機視覺的遷移學習

系列文章目錄 pytorch學習筆記&#xff08;一&#xff09;-- pytorch深度學習框架基本知識了解 pytorch學習筆記&#xff08;二&#xff09;-- pytorch模型開發步驟詳解 pytorch學習筆記&#xff08;三&#xff09;-- TensorBoard的介紹 pytorch學習筆記&#xff08;四&…

數字IC后端培訓教程之數字后端項目典型項目案例解析

數字IC后端低功耗設計實現案例分享(3個power domain&#xff0c;2個voltage domain) Q1: 電路如下圖&#xff0c;clk是一個很慢的時鐘test_clk&#xff08;屬于DFT的)&#xff0c;DFF1與and 形成一個clock gating check。跑pr 發現&#xff0c;時鐘樹綜合CTS階段&#xff08;C…

2025 Data Whale x PyTorch 安裝學習筆記(Windows 版)

一、Anaconda 的安裝與基本操作 1. 安裝 Anaconda/miniconda 官方鏈接&#xff1a;Anaconda | Individual Edition 根據系統版本選擇合適的安裝包下載并安裝。 2. 檢驗安裝 打開 “開始” 菜單&#xff0c;找到 “Anaconda Prompt”&#xff08;一般在 Anaconda3 文件夾…

mac OS上docker安裝zookeeper

拉取鏡像&#xff1a;$ docker pull zookeeper:3.5.7 3.5.7: Pulling from library/zookeeper 3.5.7: Pulling from library/zookeeper 3.5.7: Pulling from library/zookeeper no matching manifest for linux/arm64/v8 in the manifest list entries報錯&#xff1a;由于時M3…

設備通過4G網卡接入EasyCVR視頻融合平臺,出現無法播放的問題排查和解決

EasyCVR視頻融合平臺作為支持多協議接入、多設備集中管理的綜合性視頻解決方案&#xff0c;可實現各類終端設備的視頻流匯聚與實時播放。近期收到用戶反饋&#xff0c;在EasyCVR平臺接入設備后出現視頻流無法播放的情況。為幫助更多用戶快速排查同類問題&#xff0c;現將具體處…

板凳-------Mysql cookbook學習 (十二--------3)

第二章 抽象數據類型和python類 2.5類定義實例&#xff1a; 學校人事管理系統中的類 import datetimeclass PersonValueError(ValueError):"""自定義異常類"""passclass PersonTypeError(TypeError):"""自定義異常類""…

css flex 布局中 flex-direction為column,如何讓子元素的寬度根據內容自動變化

在 display: flex 且 flex-direction: column 的布局中&#xff0c;默認情況下子元素會占滿容器的寬度。要讓子元素的寬度根據內容自適應&#xff0c;而不是自動拉伸填滿父容器&#xff0c;你可以這樣處理&#xff1a;? 解決方案一&#xff1a;設置子元素 align-self: start 或…

性能優化實踐:Modbus 在高并發場景下的吞吐量提升(二)

四、Modbus 吞吐量提升實戰策略4.1 優化網絡配置選擇合適的網絡硬件是提升 Modbus 通信性能的基礎。在工業現場&#xff0c;應優先選用高性能的工業級交換機和路由器。工業級交換機具備更好的抗干擾能力和穩定性&#xff0c;其背板帶寬和包轉發率更高&#xff0c;能夠滿足高并發…

上傳ipa到appstore的幾種工具

無論是用原生開發也好&#xff0c;使用uniapp或flutter開發也好&#xff0c;最好打包好的APP是需要上架appstore的。而在app store connect上架的時候&#xff0c;需要上傳ipa文件到app store的構建版本上。因此&#xff0c;需要上傳工具。下面分析下幾種上傳工具的優缺點&…

數控調壓BUCK電路 —— 基于TPS56637(TI)

0 前言 本文基于 TI 的 TPS56637 實現一個支持調壓的 BUCK 電路&#xff0c;包含從零開始詳細的 原理解析、原理圖、PCB 及 實測數據 本文屬于《DIY迷你數控電源》系列&#xff0c;本系列我們一起實現一個簡單的迷你數控電源 我是 LNY&#xff0c;一個在對嵌入式的所有都感興…

prometheus UI 和node_exporter節點圖形化Grafana

prometheus UI 和node_exporter節點圖形化Grafana 先簡單的安裝一下 進行時間的同步操作安裝Prometheus之前必須要先安裝ntp時間同步&#xff0c;因為prometheus server對系統時間的準確性要求很高&#xff0c;必須保證本機時間實時同步。# 用crontab進行定時的時間的同步 yum …

RabbitMQ—TTL、死信隊列、延遲隊列

上篇文章&#xff1a; RabbitMQ—消息可靠性保證https://blog.csdn.net/sniper_fandc/article/details/149311576?fromshareblogdetail&sharetypeblogdetail&sharerId149311576&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link 目錄 1 TTL …