VUE從入門到精通二:ref、reactive、computed計算屬性、watch監聽、組件之間的通信

目錄

一、ref、reactive創建響應式對象

1、ref()

2、reactive()

3、ref和reactive的區別

二、computed計算屬性

1、什么是計算屬性computed

2、計算屬性computed和函數方法的區別

3、計算屬性computed的優勢

三、watch監聽函數

1、什么是watch?

2、基本語法

3、深度監聽

4、使用字符串路徑監聽嵌套屬性

5、動態添加watcher

6、立即執行watcher

7、一次性監聽

8、停止watcher

9、watch vs watchEffect監聽方式對比

10、watch與computed的區別

11、watch vue3與vue2的對比

12、性能優化建議

13、完整示例

四、組件之間的通信

1、Props(父傳子)

?2、Emit(子傳父)

3、Provide / Inject(祖先傳后代)

4、Vuex全局事件總線(狀態管理)


一、ref、reactive創建響應式對象

1、ref()

在Vue 3中,ref是一個函數,用于創建一個響應式引用。它可以定義基本數據類型(如字符串、數字、布爾值等)。雖然也可用于創建對象和數組,但更推薦使用reactive。使用ref時,需要通過.value屬性來訪問和修改數據。

const copy_address_type = ref('') ?// 地址同步文案
const exemption_fax = ref(0.00) //消費稅
const exemption_no_show = ref(false)

2、reactive()

reactive它更適用于創建對象和數組。reactive會將整個對象或數組轉換為響應式的,這意味著對象或數組中的每個屬性都會被代理。

const form_data = reactive({id: '', type:'', first_name: '',last_name: '',email: '',phone: '',institution: '',postcode: '',address: '',city: '',state_input: '',state: '',country: '', set_copy_address: ''
})
const country_data = ref([])

3、ref和reactive的區別

a.數據類型:ref適用于基本數據類型及復雜對象,而reactive主要用于復雜對象及嵌套數據結構。

b.訪問方式:ref通過.value屬性訪問,而reactive直接通過屬性訪問。

c.響應性追蹤:ref追蹤單個獨立的引用,reactive追蹤整個對象及其內部屬性。

d.可變性:ref的引用值可以重新賦值,而reactive對象本身是不可重新賦值的,只能修改其內部屬性。

二、computed計算屬性

1、什么是計算屬性computed

computed?是用于基于其他響應式數據動態計算新數據的工具,具有緩存機制,僅在依賴數據變化時重新計算,可顯著提升性能,如果依賴的數據不變化,computed永遠不會改變。

核心特性

?依賴緩存?:僅在依賴數據(如響應式引用)變化時重新計算,避免重復執行。 ?

?聲明式定義?:通過computed函數定義,支持復雜邏輯復用。 ?

?性能優化?:減少模板渲染時的計算開銷,提升渲染效率。

<template><div>{{ double }}</div><input v-model="count" />
</template><script setup>import { ref, computed } from 'vue';const count = ref(1);const double = computed(() => count.value * 2);
</script>

上面的例子,當文本框的count發生改變時,double數據也會發生變化。

2、計算屬性computed和函數方法的區別

function doubleFunc(count) {let double = count * 2return double}

若我們將同樣的函數定義為一個方法而不是計算屬性,兩種方式在結果上確實是完全相同的,然而,不同之處在于計算屬性值會基于其響應式依賴被緩存。一個計算屬性僅會在其響應式依賴更新時才重新計算。這意味著只要 author.books 不改變,無論多少次訪問 double 都會立即返回先前的計算結果,而不用重復執行doubleFunc函數。

這也很好的解釋了下面的計算屬性永遠不會更新,因為 Date.now() 并不是一個響應式依賴,它不會變化。

const now = computed(() => Date.now())

3、計算屬性computed的優勢

A.簡潔高效:通過計算屬性computed可以簡潔高效地實現基于其他屬性計算的屬性,避免了重復計算和代碼冗余。

B.響應式更新:計算屬性computed會自動響應依賴的變化而更新,保持界面和數據的同步。

C.緩存機制:計算屬性computed會緩存計算結果,只有在相關依賴發生改變時才會重新計算,提高了性能和效率。

三、watch監聽函數

1、什么是watch?

watch是Vue中用于監聽數據的變化并執行相應的操作。

當被監聽的數據發生變化時,會觸發一個回調函數,我們可以在這個回調函數中執行一些邏輯操作。

watch適用于需要在數據變化時執行異步或較復雜的場景。

2、基本語法

export default {setup() {const count = ref(0);watch(count, (newVal, oldVal) => {console.log(`count changed from ${oldVal} to ${newVal}`);});return { count,};}
};

3、深度監聽

對于對象或數組的監視,默認情況下,Vue不會遞歸地監視對象內部屬性的變化。如果你需要深度監視,vue2中可以設置deep選項為true。Vue3中你可以使用watchEffect或者watch函數,并通過提供一個回調函數來訪問和監視這些深層屬性。

Vue2深度監聽

export default {data() {return {user: {name: '張三',age: 25}}},watch: {user: {handler(newValue, oldValue) {console.log('user對象變化了', newValue, oldValue)},deep: true // 開啟深度監聽}}
}

VUE3深度監聽

import { ref, watchEffect } from 'vue';const obj = ref({nested: {prop: 'value'}
});watchEffect(() => {console.log(obj.value.nested.prop); // 訪問深層屬性
});// 更新深層屬性時,控制臺將顯示新值
obj.value.nested.prop = 'new value';

深度監聽原理:

    4、使用字符串路徑監聽嵌套屬性

    const city = computed(() => state.user.address.city);
    watch(city, (newValue, oldValue) => {console.log(`City changed from ${oldValue} to ${newValue}`);
    });

    5、動態添加watcher

    如果你需要在組件的生命周期內動態添加watcher,可以使用Vue實例的$watch方法

    export default {mounted() {this.$watch('message', (newVal, oldVal) => {console.log(`message changed from ${oldVal} to ${newVal}`);});}

    6、立即執行watcher

    默認情況下,watch只會在數據變化時觸發回調函數,而不會在初始化時執行。

    如果需要在初始化時就執行一次回調函數,可以設置immediate: true。

    watch(() => obj.value.nested.prop, // 監視深層屬性(newValue, oldValue) => {console.log(`Prop changed from ${oldValue} to ${newValue}`);},{ immediate: true } // 立即執行一次回調
    );

    7、一次性監聽

    可以使用once: true選項來設置只監聽一次變化
    // 使用 once 選項讓 watch 只監聽一次

    watch(count, (newValue, oldValue) => {console.log(`Count changed from ${oldValue} to ${newValue}`);
    }, { once: true });

    8、停止watcher

    當你使用$watch方法添加watcher時,可以通過返回的取消函數來停止watcher:

    const count = ref(0);
    let stopWatch;
    stopWatch = watch(count, (newVal, oldVal) => {console.log(`Count changed from ${oldVal} to ${newVal}`);
    });
    onUnmounted(() => {stopWatch(); // 確保在組件卸載時停止watcher
    });

    9、watch vs watchEffect監聽方式對比

    watch需要明確指定要監聽的數據源,而watchEffect會自動收集其內部所使用的所有響應式依賴。
    watch可以訪問被監聽狀態的前一個值和當前值,而watchEffect只能訪問當前值。
    watchEffect會在組件初始化時立即執行一次,相當于設置了immediate: true的watch。

    const count = ref(0)
    const message = ref('Hello')// watchEffect會自動監聽回調函數中使用的所有響應式數據
    watchEffect(() => {console.log(`count: ${count.value}, message: ${message.value}`)
    })
    // 等價于以下watch寫法
    watch([count, message], ([newCount, newMessage]) => {console.log(`count: ${newCount}, message: ${newMessage}`)
    }, { immediate: true })

    10、watch與computed的區別

    特性

    watch

    computed

    用途

    監聽數據變化并執行副作用

    計算并返回新值

    緩存

    無緩存機制

    有緩存,只在依賴變化時重新計算

    返回值

    無返回值

    有返回值

    適用場景

    數據變化時執行異步操作或復雜邏輯

    依賴其他數據計算出新值

    執行時機

    數據變化后執行

    依賴變化時立即計算新值

    11、watch vue3與vue2的對比

    // Vue 2 選項式 API
    watch: {user: {handler(newVal) { /*...*/ },deep: true}
    }// Vue 3 組合式 API(更靈活)
    const user = reactive({/*...*/})
    watch(user, (newVal) => {/*...*/}, { deep: true })

    12、性能優化建議

    避免過度深度監聽:只對必要對象開啟
    使用精確監聽路徑

    watch(() => user.address.city, (newCity) => {...})及時清理監聽
    const stopWatch = watch(...)
    onUnmounted(stopWatch) // 組件卸載時停止監聽

    13、完整示例

    const user = reactive({id: 1,info: {name: '張三',address: {city: '北京',street: '朝陽區'}}
    })// 深度監聽整個用戶對象
    watch(user,(newUser) => {console.log('用戶信息已修改,自動保存...')autoSave(newUser)},{ deep: true, immediate: true }
    )// 精確監聽城市變化
    watch(() => user.info.address.city,(newCity) => {updateMap(newCity)}
    )

    四、組件之間的通信

    1、Props(父傳子)

    父組件通過props向下傳遞數據給子組件。這是最常見的父子組件通信方式。

    父組件

    <template><ChildComponent :message="parentMessage" />
    </template><script setup>
    import ChildComponent from './ChildComponent.vue';
    import { ref } from 'vue';const parentMessage = ref('Hello from parent');
    </script>

    子組件

    <template><div>{{ message }}</div>
    </template><script setup>
    defineProps({message: String
    });
    </script>

    ?2、Emit(子傳父)

    子組件通過emit向父組件發送事件和數據。

    子組件

    <template><button @click="sendMessage">Send Message</button>
    </template><script setup>
    import { defineEmits } from 'vue';const emit = defineEmits(['updateMessage']);function sendMessage() {emit('updateMessage', 'Hello from child');
    }
    </script>

    父組件

    <template><ChildComponent @updateMessage="handleMessage" />
    </template><script setup>
    import ChildComponent from './ChildComponent.vue';
    import { ref } from 'vue';const childMessage = ref('');
    function handleMessage(msg) {childMessage.value = msg;
    }
    </script>

    3、Provide / Inject(祖先傳后代)

    provide和inject可以用于跨多級組件傳遞數據,非常適合在深層嵌套的組件結構中通信。

    祖先組件

    <template><DescendantComponent />
    </template><script setup>
    import { provide, ref } from 'vue';
    import DescendantComponent from './DescendantComponent.vue';const message = ref('Hello from ancestor');
    provide('message', message); // 提供數據給后代組件使用
    </script>

    后代組件

    <template><div>{{ message }}</div>
    </template><script setup>
    import { inject } from 'vue';
    const message = inject('message'); // 注入數據從祖先組件接收數據
    </script>

    4、Vuex全局事件總線(狀態管理)

    對于更復雜的應用,可以使用Vuex進行狀態管理,實現任意跨組件的通信。Vuex提供了一個集中存儲管理應用所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。

    使用:

    第一步:#src/store/index.js 創建vuex模塊文件,開始使用vuex

    在一個模塊化的打包系統中,您必須顯式地通過 `Vue.use()` 來安裝 Vuex:

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)

    第二步:#實例化Vuex.store ,并進行相關配置

    export default new Vuex.Store({state: {//存儲狀態},mutations: {//變更store中的狀態},actions: {//類似于mutation,//action提交的是mutation,而不是直接變更狀態//action可以包含異步操作},getters:{//state的派生狀態  },modules: {//將store分割成模塊}
    })

    第三步:#在main.js中,vue實例對象中注冊store

    import store from './store'
    new Vue({store,render: h => h(App)
    }).$mount('#app')

    每一個 Vuex 應用的核心就是 store(倉庫)。“store”基本上就是一個容器,它包含著你的應用中大部分的狀態 (state)

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

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

    相關文章

    構建AI智能體:十二、給詞語繪制地圖:Embedding如何構建機器的認知空間

    我們理解“蘋果”這個詞&#xff0c;能聯想到一種水果、一個公司、或者牛頓的故事。但對計算機而言&#xff0c;“蘋果”最初只是一個冰冷的符號或一串二進制代碼。傳統的“One-Hot”編碼方式&#xff08;如“蘋果”是[1,0,0,...]&#xff0c;“香蕉”是是[0,1,0,...]&#xff…

    突擊復習清單(高頻核心考點)

    &#x1f512; 鎖的作用與使用&#xff08;synchronized vs ReentrantLock&#xff09; 面試官為什么問&#xff1a;考察你對并發編程基礎的掌握程度。 速記答案&#xff1a; 作用&#xff1a;保證線程安全&#xff0c;解決多線程環境下對共享資源訪問的數據不一致問題。 synch…

    2025年視頻大模型匯總、各自優勢及視頻大模型競爭焦點

    文章目錄一、國際主流視頻大模型1. OpenAI Sora Turbo2. Google Veo 33. Runway Gen-3 Alpha二、國內主流視頻大模型1. 快手可靈AI2. 愛詩科技PixVerse V33. 阿里巴巴通義萬相2.14. 生數科技Vidu Q15. 字節跳動即夢AI三、核心趨勢與競爭焦點一、國際主流視頻大模型 1. OpenAI …

    Android - 用Scrcpy 將手機投屏到Windows電腦上

    工作生活當中&#xff0c;常常需要操作手機&#xff0c;但是用手操作顯然不如用鍵盤快。 再一個&#xff0c;你看視頻的時候&#xff0c;想做一些筆記&#xff0c;那你也得截個圖啦之類的&#xff0c; 那如果直接在電腦上能看也是非常方便的&#xff0c;這都需要投屏手機到電…

    AlmaLinux 上 Python 3.6 切換到 Python 3.11

    在 AlmaLinux 上將默認的 Python 3.6 升級或切換到 Python 3.11 是一個常見的需求。請注意&#xff0c;直接替換系統自帶的 Python 3.6 是非常危險的&#xff0c;因為許多系統工具&#xff08;如 yum/dnf 包管理器&#xff09;都依賴于它&#xff0c;盲目刪除或修改可能會導致系…

    基于RBF-GA的鋁/鎂異材FSLW工藝參數優化研究

    課題&#xff1a;基于RBF-GA的鋁/鎂異材FSLW工藝參數優化研究 1. 引言 (Introduction) 研究背景與意義&#xff1a; 輕量化需求&#xff1a;鋁&#xff08;Al&#xff09;和鎂&#xff08;Mg&#xff09;合金是航空航天、新能源汽車等領域實現輕量化的關鍵材料。實現二者的可靠…

    【Prometheus】Prometheus監控Docker實戰

    &#x1f47b;創作者&#xff1a;丶重明 &#x1f47b;創作時間&#xff1a;2025年8月23日 &#x1f47b;擅長領域&#xff1a;運維 目錄前言什么是Prometheus和cAdvisorPrometheuscAdvisor部署操作部署cAdvisor部署Prometheus指標說明cpu相關指標內存相關指標磁盤相關指標網絡…

    2.7 提示詞調優編碼實戰(二)

    目錄 四,提示詞模版優化 - 格式化 4.1 代碼示例 4.2 任務描述 4.3 模型輸出格式化 4.4 用戶輸入 4.5 輸出結果 四,提示詞模版優化 - 格式化 在簡單提示詞的基礎上,我們對提示詞模版中各部分進行格式化。包括任務描述增加了相應的字段。 同時對輸出增加了更多的定義和…

    Kafka如何保證「消息不丟失」,「順序傳輸」,「不重復消費」,以及為什么會發生重平衡(reblanace)

    前言 上一篇文章總結了kafka為什么快&#xff0c;下面來總結一下&#xff0c;kafka高頻的常見的問題。內容有點多&#xff0c;全部看完需要有一定的耐心。 kafka如何保證消息不丟失 Producer端 要保證消息不丟失&#xff0c;第一點要做的就是要保證消息從producer端發送到了…

    原子操作匯編實現:原理、流程與代碼解析

    &#x1f52c; 原子操作匯編實現&#xff1a;原理、流程與代碼解析 引用&#xff1a;VC/C Intel x86 內聯匯編實現 “Interlocked” 原子變量各種操作 &#x1f31f; 引言&#xff1a;原子操作的重要性 在多線程編程中&#xff0c;原子操作是確保數據一致性的關鍵機制。本文…

    【WRF理論第十九期】內陸湖泊、水體的處理方式

    目錄 WRF 模型中湖泊模擬概述 湖泊模型(Lake Model)集成 新增湖泊數據支持(如 WUDAPT + MODIS) LAKE_DEPTH Noah-MP + 湖泊模型聯合使用 namelist.input 配置說明 WRF 代碼更新 參考 論壇-WRF 湖泊模型(WRF-Lake model)與 SST 更新 WRF 模型中湖泊模擬概述 湖泊模型(La…

    【滲透測試】SQLmap實戰:一鍵獲取MySQL數據庫權限

    注&#xff1a;所有技術僅用于合法安全測試與防御研究&#xff0c;未經授權的攻擊行為屬違法犯罪&#xff0c;將承擔法律責任。一、SQLmap常規用法注意存放路徑&#xff1a;C:\Users\neo\AppData\Local\sqlmap\output1、列出詳細過程和數據庫列表sqlmap -u http://192.168.61.2…

    LeetCode 第464場周賽 第三天

    1. 3658 奇數和與偶數和的最大公約數&#xff08;歐幾里得&#xff09; 鏈接&#xff1a;題目鏈接 題解&#xff1a; 題解時間復雜度O(logmin(a, b))&#xff1a; 獲得前n個奇、偶數的總和&#xff0c;由于數列為等差數列&#xff0c;等差數列和公式&#xff1a;(a1 an) * n …

    IntelliJ IDEA 集成 ApiFox 操作與注解規范指南

    一、IDEA裝入Apifox 1.安裝Apifox Helper 說明:在 IntelliJ IDEA 中安裝 ApiFox Helper 插件。 2.打開Apifox 說明:點擊 設置,在菜單中選擇 API訪問令牌。在彈出的窗口中輸入任意名稱,并選擇令牌的有效期(為了方便,我這里選擇了 無期限)。生成令牌后,由于 令牌只能復…

    C++---雙指針

    在C編程中&#xff0c;雙指針算法是一種高效的解題思路&#xff0c;其核心是通過設置兩個指針&#xff08;或索引&#xff09;遍歷數據結構&#xff08;如數組、鏈表、字符串等&#xff09;&#xff0c;利用指針的移動規則減少無效操作&#xff0c;從而將時間復雜度從暴力解法的…

    【LLM】GLM-4.5模型架構和原理

    note 文章目錄note一、GLM-4.5模型二、Slime RL強化學習訓練架構Reference一、GLM-4.5模型 大模型進展&#xff0c;GLM-4.5技術報告,https://arxiv.org/pdf/2508.06471&#xff0c;https://github.com/zai-org/GLM-4.5&#xff0c;包括GLM-4.5&#xff08;355B總參數&#xff…

    LLM 中增量解碼與模型推理解讀

    在【LLM】LLM 中 token 簡介與 bert 實操解讀一文中對 LLM 基礎定義進行了介紹&#xff0c;本文會對 LLM 中增量解碼與模型推理進行解讀。 一、LLM 中增量解碼定義 增量解碼&#xff08;Incremental Decoding&#xff09;是指在自回歸文本生成過程中&#xff0c;模型每次只計…

    1.Spring Boot:超越配置地獄,重塑Java開發體驗

    目錄 一、Spring框架&#xff1a;偉大的基石 歷史背景與挑戰 Spring的革命性貢獻 新的挑戰&#xff1a;配置地獄 二、Spring Boot&#xff1a;約定大于配置的革命 四大核心特性 1. 快速創建獨立應用 2. 自動配置&#xff1a;智能化的魔法 3. 起步依賴&#xff1a;依賴管…

    assert使用方法

    assert 是 Python 中用來進行 調試 和 驗證 的一個關鍵字&#xff0c;它用于測試一個 條件表達式 是否為真。如果條件為假&#xff0c;assert 會拋出一個 AssertionError 異常&#xff0c;通常帶有錯誤信息。語法&#xff1a;assert condition, "Error message"condi…