vue3 教程(中)

偵聽器

用于偵聽指定變量,當其響應式狀態變化時觸發回調函數。

watch()

watch() 需明確指定偵聽的數據源,并且僅當數據源變化時,才會執行回調,在創建偵聽器時,不會執行回調,可以獲取到數據源變化前后的值。

  • 第一個參數為“數據源”,可以是一個 ref (包括計算屬性)、一個響應式對象、一個 getter 函數、或多個數據源組成的數組
  • 第二個參數為回調函數

偵聽–響應式變量 / 計算屬性

const x = ref(0)
watch(x, (newX) => {console.log(`x is ${newX}`)
})

偵聽–響應式對象

會隱式地創建一個深層偵聽器,對象的屬性和嵌套屬性發生變化時,都會觸發回調

const obj = reactive({ count: 0 })
watch(obj, (newValue, oldValue) => {// 此處 `newValue` 和 `oldValue` 是相等的,因為它們是同一個對象!
})

若用getter 函數返回響應式對象 ,則只有在返回不同的對象時,才會觸發回調:

watch(() => state.someObject,() => {// 僅當 state.someObject 被替換時觸發}
)

通過添加 deep 選項,可以將其強制轉成深層偵聽器(即當對象的屬性和嵌套屬性發生變化時觸發回調)

watch(() => state.someObject,(newValue, oldValue) => {// 此處 `newValue` 和 `oldValue` 是相等的,除非 state.someObject 被整個替換了},{ deep: true }
)

偵聽–對象的屬性

方案1:用一個返回該屬性的 getter 函數

// 偵聽obj對象的count屬性
watch(() => obj.count,(count) => {console.log(`count is: ${count}`)}
)

方案2:使用 toRefs

import { ref, toRefs, watch } from "vue";
let obj = ref({ count: 30 });
let { count } = toRefs(obj.value);
watch(count, (newValue, oldValue) => {});

不能直接偵聽響應式對象的屬性值,因為屬性值非響應式

const obj = reactive({ count: 0 })// 錯誤,因為 watch() 得到的參數是一個 number
watch(obj.count, (count) => {console.log(`count is: ${count}`)
})

偵聽-- getter 函數

const x = ref(0)
const y = ref(0)watch(() => x.value + y.value,(sum) => {console.log(`sum of x + y is: ${sum}`)}
)

偵聽-- 多個數據源

// 多個來源組成的數組
watch([x, () => y.value], ([newX, newY]) => {console.log(`x is ${newX} and y is ${newY}`)
})

watchEffect()

watchEffect()在創建偵聽器時,會立即執行一遍回調,并從中自動分析出依賴的數據源(其響應性依賴關系不那么明確),當數據源發生改變時,再次觸發回調。無法獲取到數據源變化前的值。

watchEffect(async () => {const response = await fetch(url.value)data.value = await response.json()
})

上例中,在頁面創建時會先請求 url.value 接口獲得初始數據,并自動追蹤 url.value
url.value 變化時,會再次執行回調,訪問新的接口獲取數據。

改變回調的觸發時機

默認情況下,偵聽器回調會在 Vue 組件更新之前被調用(在偵聽器回調中訪問的 DOM 是被 Vue 更新之前的狀態)

添加 flush: 'post' 選項可以讓偵聽器回調在 Vue 組件更新之后再調用,這樣就能在偵聽器回調中訪問被 Vue 更新之后的 DOM 啦!

watch(source, callback, {flush: 'post'
})watchEffect(callback, {flush: 'post'
})

后置刷新的 watchEffect() 可以直接用 watchPostEffect()

import { watchPostEffect } from 'vue'watchPostEffect(() => {/* 在 Vue 更新后執行 */
})

停止偵聽器

同步語句創建的偵聽器,會在組件卸載時自動停止。
異步回調創建的偵聽器,必須手動停止它,以防內存泄漏。

setTimeout(() => {watchEffect(() => {})
}, 100)

手動停止偵聽器的方法是調用 watch 或 watchEffect 返回的函數

const unwatch = watchEffect(() => {})
unwatch()

異步創建偵聽器的情況很少,如果需要等待一些異步數據,可以使用條件式的偵聽邏輯:

// 需要異步請求得到的數據
const data = ref(null)watchEffect(() => {if (data.value) {// 數據加載后執行某些操作...}
})

模板引用 ref

用于直接訪問底層 DOM 元素,即 vue2 中的 $refs

  <input ref="input" />
import { ref, onMounted } from 'vue'// 聲明一個ref變量來存放該元素的引用,變量名必須和模板里的 ref 屬性值相同
const input = ref(null)onMounted(() => {// 頁面加載后,輸入框自動獲得焦點input.value.focus()
})

只可以在組件掛載后才能訪問模板引用
若偵聽模板引用 ref 的變化,需考慮到其值為 null 的情況:

watchEffect(() => {if (input.value) {input.value.focus()} else {// 此時還未掛載,或此元素已經被卸載(例如通過 v-if 控制)}
})

ref 綁定函數

<input :ref="(el) => { /* 將 el 賦值給一個數據屬性或 ref 變量 */ }">
  • 綁定函數需使用 :ref
  • 每次Dom更新時函數都會被調用
  • Dom被卸載時,函數也會被調用一次,此時 el 參數的值是 null

子組件上的 ref

若子組件使用的是選項式 API 或沒有使用 <script setup> ,則對子組件的模板引用即子組件的 this,可以直接訪問子組件的屬性和方法。(但仍推薦用標準的 props 和 emit 接口來實現父子組件交互)

使用了 <script setup> 的子組件是默認私有的:父組件無法訪問私有子組件中的任何東西,除非子組件通過 defineExpose 宏顯式暴露。

<script setup>
import { ref } from 'vue'const a = 1
const b = ref(2)defineExpose({a,b
})
</script>

父組件通過模板引用獲取到的實例類型為 { a: number, b: number } (ref 都會自動解包,和一般的實例一樣)。

父子組件

父組件中使用子組件 import

vue3 中導入后就能直接使用,無需像 vue2 中進行注冊

<script setup>
import ButtonCounter from './ButtonCounter.vue'
</script>
<template><ButtonCounter />
</template>

子組件接收父組件傳入的數據 props

子組件用 defineProps() 接收父組件傳入的數據

<script setup>
defineProps(['title'])
</script><template><h4>{{ title }}</h4>
</template>

defineProps() 的參數和 props 選項的值相同

defineProps({title: String,likes: Number
})

搭配 TypeScript 使用類型標注來聲明 props

<script setup lang="ts">
defineProps<{title?: stringlikes?: number
}>()
</script>

選項式風格中,props 對象會作為 setup() 函數的第一個參數被傳入:

export default {props: ['title'],setup(props) {console.log(props.title)}
}

子組件觸發自定義事件 emits

組件觸發的事件不會冒泡,父組件只能監聽直接子組件觸發的事件。

父組件–在引入的子組件上綁定事件

<BlogPost @enlarge-text="postFontSize += 0.1"/>

子組件–用 defineEmits() 聲明事件

<button @click="$emit('enlarge-text')">Enlarge text</button>
<script setup>
defineEmits(['enlarge-text']) // 多個事件則為 defineEmits(['inFocus', 'submit'])
</script>

選項式風格中,通過 emits 選項定義組件會拋出的事件,并用 setup() 的第二個參數(上下文對象)訪問 emit 函數:

export default {emits: ['enlarge-text'],setup(props, ctx) {ctx.emit('enlarge-text')}
}

事件傳參

子組件

<button @click="$emit('increaseBy', 1)"></button>

父組件

<MyButton @increase-by="(n) => count += n" />

<MyButton @increase-by="increaseCount" />
function increaseCount(n) {count.value += n
}

子組件繼承樣式

vue2 中限定只能有一個根節點,父組件中給子組件添加的樣式,都會渲染在子組件的根節點上,如:

<!-- 子組件 -->
<p class="child">你好</p>
<!-- 父組件使用子組件時,添加了新的樣式 father -->
<MyComponent class="father" />

最終渲染的效果為:

<p class="child father">你好</p>

vue3 中支持多個根節點,所以需要通過 $attrs 指定具體哪些節點繼承父組件添加的樣式。

<!-- 子組件:在需要繼承樣式的元素上,添加  :class="$attrs.class" -->
<p :class="$attrs.class">你好</p>
<span>我是朝陽</span>
<!-- 父組件使用子組件時,添加了新的樣式 father -->
<MyComponent class="father" />

最終渲染的效果為:

<p class="father">你好</p>
<span>我是朝陽</span>

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

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

相關文章

Flutter 父子組件通信

在Flutter 中父組件調用子組件的方法可以通過GlobalKey實現&#xff0c;而子組件調用父組件方法可以通過回調函數實現。 父組件 class _MyHomePageState extends State<MyHomePage> {final GlobalKey<LoadPencilState> loadPencilKey GlobalKey<LoadPencilSt…

react中虛擬dom,diff,fiber - 初級了解

借鑒&#xff1a; 「React深入」一文吃透虛擬DOM和diff算法 - 掘金 (juejin.cn) 虛擬dom、fiber、渲染dom、dom-diff - 掘金 (juejin.cn) 未閱讀源碼&#xff0c;了解層面&#xff0c;后續可以深入了解 1.虛擬DOM ①.結構上&#xff1a;虛擬DOM比真實DOM輕很多 ②.操作上&…

主流的低代碼平臺有哪些?程序員應該如何與低代碼相處?

本文主要闡述低代碼的概念&#xff0c;介紹目前主流的低代碼平臺&#xff0c;總結低代碼平臺的典型特征、存在優勢以及未來發展趨勢。并站在程序員的角度&#xff0c;分析如何在已經到來的低代碼戰爭中&#xff0c;找到自己的定位&#xff0c;一展所長。 什么是低代碼&#xff…

脈沖寬度基礎知識簡介

脈沖寬度是指脈沖所能達到的最大值所持續的周期時間。脈沖寬度是電子領域中一個重要的概念&#xff0c;它與脈沖重復間隔和占空比等參數密切相關。 脈沖寬度通常用于電信號的測量&#xff0c;可以用來描述脈沖的形狀、幅度和寬度等特性。在雷達和電源領域中&#xff0c;脈沖寬度…

Flink 替換 Logstash 解決日志收集丟失問題

在某客戶日志數據遷移到火山引擎使用 ELK 生態的案例中&#xff0c;由于客戶反饋之前 Logstash 經常發生數據丟失和收集性能較差的使用痛點&#xff0c;我們嘗試使用 Flink 替代了傳統的 Logstash 來作為日志數據解析、轉換以及寫入 ElasticSearch 的組件&#xff0c;得到了該客…

實現一個計算機

圖片&#xff1a; 實現代碼&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>body {padding: 20px;font-family: Arial;}.calc-wrap {width: 300px;bor…

VL06O報表添加增強字段

業務描述 用戶需要在VL06O事務代碼下進行批量交貨過賬&#xff0c;現有的篩選條件不太適用當前公司的業務&#xff0c;需要在報表中新增三個交貨單增強字段&#xff0c;方便其篩選&#xff08;選擇屏幕沒有加&#xff0c;用戶在報表里用標準按鈕功能自己篩選&#xff09; 效果…

十一 動手學深度學習v2計算機視覺 ——微調

一、網絡架構 一個神經網絡一般可以分成兩塊 特征抽取&#xff0c;將原始像素變成容易線性分割的特征。線性分類器來做分類。 二、訓練 是一個目標數據集上的正常訓練任務&#xff0c; 但使用更強的正則化 使用更小的學習率使用更少的數據迭代 源數據集遠遠復雜于目標數據集…

藍橋杯算法雙周賽心得——迷宮逃脫(dp)

大家好&#xff0c;我是晴天學長&#xff0c;dp版的來啦&#xff0c;可以是受益匪淺啊&#xff0c;需要的小伙伴可以關注支持一下哦&#xff01;后續會繼續更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .迷宮逃脫 迷官逃脫[算法賽] 問題描述 在數學王國中&#xff0c;存…

便攜式心電圖機方案_基于MT6735平臺的手持心電圖機

便攜式心電圖機具備體積小、易攜帶、兼容12導模式的特點&#xff0c;通過工頻濾波、基線濾波和肌電濾波等處理&#xff0c;能夠獲得更精準的心電圖譜。該設備可以與醫院信息系統(HIS)相連接&#xff0c;實現患者信息的共享。采集的心電數據可以通過無線方式發送到心電判讀平臺&…

企業建數倉的第一步是選擇一個好用的ETL工具

當企業決定建立數據倉庫&#xff08;Data Warehouse&#xff09;&#xff0c;第一步就是選擇一款優秀的ETL&#xff08;Extract, Transform, Load&#xff09;工具。數據倉庫是企業數據管理的核心&#xff0c;它存儲、整合并管理各種數據&#xff0c;為商業決策和數據分析提供支…

PC8250(CC-CV控制)5V/8A同步降壓恒流恒壓軟啟動帶EN功能只需極少外圍元件

概述 PC8250是一個同步降壓轉換器輸出電流至8A。它的設計允許操作電源電壓范圍從9V到42V。外部關閉功能可以通過邏輯電平來控制COMP/EN引腳下降&#xff0c;然后進入待機模式。外部補償使反饋控制具有良好的線路和負載調節&#xff0c;外部設計靈活。PC8250在CC&#xff08;恒定…

【讀懂AUTOSAR規范】PduR 緩存分配(Buffer allocation)

1. 前言 PDU路由器模塊支持將I-PDU從一個源總線網關到一個或多個目標總線。與從/到本地模塊的傳輸和接收不同,PDU路由器模塊必須同時充當接收器和發射器,并且在某些情況下還提供I-PDU的緩沖。網關需求被有意地分離,以便在不需要網關的情況下高效實現PDU路由器模塊。如果PDU…

華三無線控制器WX2540H配合準入做Portal認證

數據通信 - 建設篇 - 無線 第四章 華三無線控制器WX2540H配合準入做Portal認證 數據通信 - 建設篇 - 無線系列文章回顧華三無線控制器WX2540H配合準入做Portal認證前言其他配置優化參考來源系列文章回顧 第一章 華三無線控制器配置本地轉發 第二章 華三無線控制器配置802.1X認…

Redis-Day1基礎篇(初識Redis, Redis常見命令, Redis的Java客戶端)

Redis-Day1基礎篇 初識Redis認識NoSQL認識Redis安裝Redis啟動RedisRedis客戶端 Redis命令數據結構介紹通用命令操作命令StringHashListSetSortedSet Redis的Java客戶端客戶端對比Jedis客戶端Jedis快速入門Jedis連接池 SpringDataRedis客戶端SpringDataRedis概述SpringDataRedis…

boardmix AI思維導圖,一鍵自動生成思維導圖!

在日常學習和工作中&#xff0c;我們常常需要記憶和整理大量的知識點和思維結構。 此時&#xff0c;思維導圖的存在就大大方便了我們的工作。與傳統的文本筆記不同&#xff0c;思維導圖可以結合文字、圖像、顏色等多種元素&#xff0c;幫助我們更好地整理和分析知識的關系&…

centos7上用docker部署redis

1. 下載redis鏡像 docker pull redis docker images # 查看鏡像是否下載成功2. 安裝redis容器 2.1 先準備好配置文件redis.conf vi /data/redis/redis.conf寫入配置信息&#xff0c;appendonly yes&#xff0c;如果需要給redis配置密碼&#xff0c;可以寫入requirepass root…

如何選擇更快更穩定的存儲服務器

如何選擇更快更穩定的存儲服務器 存儲介質&#xff1a;存儲服務器的主要存儲介質包括固態硬盤&#xff08;SSD&#xff09;和機械硬盤&#xff08;HDD&#xff09;。相比于機械硬盤&#xff0c;固態硬盤具有更高的讀寫速度和更低的延遲&#xff0c;因此能夠提供更快的數據傳輸…

python安裝的記錄

python setup.py install --user

(附程序)AD采集中的10種經典軟件濾波程序優缺點分析

前言 本次我們學習一下AD采集的一些簡單的軟件濾波算法并分析優缺點 本篇博客大部分是自己收集和整理&#xff0c;如有侵權請聯系我刪除。 AD采樣點的電壓多少有點起伏波動&#xff0c;經運放放大后電壓的波動如果超過ADC的分辯率&#xff0c;則顯示的值會出現波動。波動如…