前端筆記-Vue3(下)

學習參考視頻:尚硅谷Vue3入門到實戰,最新版vue3+TypeScript前端開發教程_嗶哩嗶哩_bilibili

vue3學習目標:

VUE 31、Vue3架構與設計理念
2、組合式API(Composition API)
3、常用API:ref、reactive、watch、computed
4、Vue3的生命周期
5、組件間通信(props、emit、defineModel)
6、了解插槽

Vue 生命周期鉤子詳解(Vue 2 & Vue 3 對比)

生命周期概念圖解

https://cn.vuejs.org/assets/lifecycle_zh-CN.W0MNXI0C.png

生命周期階段對比表

階段Vue 2 鉤子Vue 3 鉤子觸發時機典型用途
?創建?beforeCreatesetup()組件實例剛被創建初始化響應式數據
createdsetup()數據觀測/事件配置完成異步請求數據
?掛載?beforeMountonBeforeMount模板編譯/掛載前訪問/操作DOM前的最后機會
mountedonMounted組件掛載到DOM后操作DOM、初始化第三方庫
?更新?beforeUpdateonBeforeUpdate數據變化,DOM更新前獲取更新前的DOM狀態
updatedonUpdated虛擬DOM重新渲染后執行依賴DOM的操作
?銷毀?beforeDestroyonBeforeUnmount實例銷毀前清除定時器/取消訂閱
destroyedonUnmounted實例銷毀后清理內存/移除事件監聽

Vue 3 生命周期示例

<template><div class="demo"><h2>計數器: {{ count }}</h2><button @click="increment">增加</button><button @click="showComponent = false">卸載組件</button><ChildComponent v-if="showComponent" /></div>
</template><script setup lang="ts">
import { ref, onMounted, onUpdated, onUnmounted } from 'vue'
import ChildComponent from './ChildComponent.vue'// 1. 創建階段(setup)
const count = ref(0)
const showComponent = ref(true)console.log('1. setup階段 - 數據初始化完成')// 3. 掛載階段
onMounted(() => {console.log('3. mounted - 組件已掛載到DOM')// 這里可以安全地操作DOMdocument.title = `當前計數: ${count.value}`
})// 4. 更新階段
onUpdated(() => {console.log('4. updated - DOM已更新')// 避免在這里修改狀態,可能導致無限循環!
})// 方法
function increment() {count.value++console.log('2. 數據變化觸發更新流程')
}// 子組件示例
const ChildComponent = {setup() {onMounted(() => {console.log('子組件 mounted')})onUnmounted(() => {console.log('子組件 unmounted')})return {}},template: '<div>子組件內容</div>'
}
</script>

生命周期執行順序演示

  1. 組件初始化時:

    1. setup階段 - 數據初始化完成
    3. mounted - 組件已掛載到DOM
  2. 點擊"增加"按鈕時:

    2. 數據變化觸發更新流程
    4. updated - DOM已更新
  3. 點擊"卸載組件"時:

    子組件 unmounted

?掛載階段完整順序(父 → 子)

  1. ?父組件??setup()?執行
  2. ?父組件??onBeforeMount
  3. ?子組件??setup()?執行
  4. ?子組件??onBeforeMount
  5. ?子組件??onMounted(子組件先完成掛載)
  6. ?父組件??onMounted(父組件最后完成掛載)

常用鉤子使用場景

1. onMounted - 最常用

onMounted(async () => {// 加載初始數據const response = await fetch('/api/data')data.value = await response.json()// 初始化圖表chart = new Chart(document.getElementById('chart'), {// 配置項})
})

2. onUpdated - 謹慎使用

onUpdated(() => {// 典型用例:自動滾動到底部listContainer.value.scrollTop = listContainer.value.scrollHeight
})

3. onUnmounted - 資源清理

onUnmounted(() => {// 清除定時器clearInterval(timer)// 取消事件監聽window.removeEventListener('resize', handleResize)// 銷毀第三方庫實例chart?.destroy()
})

Vue 2 與 Vue 3 生命周期對比

關鍵區別:

  1. ?Vue 3 使用 setup 替代了 beforeCreatecreated
  2. ?所有鉤子都需要顯式導入?
  3. ?命名更語義化(unmount 替代 destroy)??
  4. ?組合式API讓相關代碼更集中?

補充 自定義Hooks

什么是自定義 Hook?

自定義 Hook 是 Vue 3 組合式 API 的核心實踐方式,本質是一個封裝了響應式邏輯的函數。它解決了兩個核心問題:

  1. ?邏輯復用? - 避免重復代碼
  2. ?關注點分離? - 讓組件更專注于模板渲染

就比如,在寫到一個組件里面存著在不同邏輯的數據和處理數據的方法時,全部都混用了

<template><div class="hooks-test"><h2>當前求和為:{{sum}}</h2><button @click="add">點我+1</button><hr><img v-for="(dog,index) in dogList" :src="dog" :key="index"><br><button @click="getDog">再來一只狗</button></div>
</template><script lang="ts" setup>import { ref,reactive } from 'vue'import axios from 'axios'    let sum = ref(0)let dogList = reactive(['https:\/\/images.dog.ceo\/breeds\/pembroke\/n02113023_2390.jpg'])function add(){sum.value += 1}// function getDog(){//   axios.get('https://dog.ceo/api/breeds/image/random')//  .then(res => {//     dogList.push(res.data.message)//   })// }async function getDog(){try {let result = await axios.get('https://dog.ceo/api/breeds/image/random')dogList.push(result.data.message)} catch (error) {alert(error)}}</script><style scoped>
.hooks-test{background-color: beige;padding: 20px;text-align: center;border: 1px solid black;
}
img{height: 200px;margin: 20px;
}
</style>

?圖示代碼又處理數字數據又處理狗狗數據,數據和處理邏輯沒有分開,導致代碼閱讀時有一定的障礙,這個時候我們就可以使用hooks自定義,將實現同一個功能所需要的數據和方法單獨封裝在一起

Hook 基礎結構

首先注意,hook命名規范是useXxxx.js/ts

1. 計數器 Hook 示例 (useCounter.ts)

import { ref, onMounted } from 'vue'export default function(initialValue = 0) {// 響應式數據const count = ref(initialValue)// 操作方法const increment = () => count.value++const decrement = () => count.value--const reset = () => count.value = initialValue// 生命周期onMounted(() => {console.log('計數器Hook已掛載')})// 暴露給組件的APIreturn {count,increment,decrement,reset}
}

2. 異步數據 Hook 示例 (useFetch.ts)

import { reactive, onMounted } from 'vue'
import axios from 'axios'export default function(url: string) {const state = reactive({data: null as any,loading: false,error: null as Error | null})const fetchData = async () => {state.loading = truetry {const response = await axios.get(url)state.data = response.data} catch (err) {state.error = err as Error} finally {state.loading = false}}onMounted(fetchData)return {...state,refetch: fetchData}
}

組件中使用 Hook

1. 基礎用法

<template><div><p>Count: {{ counter.count }}</p><button @click="counter.increment">+</button><button @click="counter.decrement">-</button><button @click="counter.reset">Reset</button></div>
</template><script setup lang="ts">
import useCounter from '@/hooks/useCounter'const counter = useCounter(10) // 初始值10
</script>

2. 組合多個 Hook

<template><div><!-- 計數器 --><div>{{ counter.count }}</div><!-- 異步數據 --><div v-if="posts.loading">Loading...</div><div v-else>{{ posts.data }}</div></div>
</template><script setup lang="ts">
import useCounter from '@/hooks/useCounter'
import useFetch from '@/hooks/useFetch'const counter = useCounter()
const posts = useFetch('/api/posts')
</script>

最佳實踐

1. 命名規范

  • 始終以 use 開頭 (useXxx)
  • 一個文件只包含一個 Hook
  • 放在 src/hooks 目錄下

2. 類型安全

// useUser.ts
import { ref } from 'vue'interface User {id: numbername: stringemail: string
}export default function() {const user = ref<User | null>(null)return {user}
}

3. 復雜 Hook 示例 (usePagination.ts)

import { reactive, computed } from 'vue'export default function(totalItems: number, perPage = 10) {const state = reactive({currentPage: 1,perPage})const totalPages = computed(() => Math.ceil(totalItems / state.perPage))const nextPage = () => {if (state.currentPage < totalPages.value) {state.currentPage++}}return {...state,totalPages,nextPage}
}

與 Vue 2 Mixins 對比

特性自定義 HookMixins
?代碼組織?按功能組織按選項合并
?命名沖突?無(可重命名解構)容易沖突
?類型支持?完整 TypeScript 支持支持有限
?邏輯復用?顯式導入全局混入
?調試?清晰的調用棧難以追蹤邏輯來源

高級技巧

1. 本地存儲 Hook (useLocalStorage.ts)

import { ref, watch } from 'vue'export default function(key: string, defaultValue: any) {const data = ref(JSON.parse(localStorage.getItem(key) || 'null') || defaultValue)watch(data, (newVal) => {localStorage.setItem(key, JSON.stringify(newVal))}, { deep: true })return data
}

2. 鼠標位置 Hook (useMouse.ts)

import { ref, onMounted, onUnmounted } from 'vue'export default function() {const x = ref(0)const y = ref(0)const update = (e: MouseEvent) => {x.value = e.pageXy.value = e.pageY}onMounted(() => window.addEventListener('mousemove', update))onUnmounted(() => window.removeEventListener('mousemove', update))return { x, y }
}

常見問題解決

1. Hook 之間共享狀態

// useSharedState.ts
import { reactive } from 'vue'const state = reactive({count: 0
})export function useSharedCounter() {const increment = () => state.count++return {count: state.count,increment}
}

2. 響應式解構問題

// ? 錯誤 - 失去響應性
const { count, increment } = useCounter()// ? 正確 - 保持響應性
const counter = useCounter()
// 在模板中使用 counter.count

(未完)?

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

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

相關文章

Git遠程操作與標簽管理

目錄 1.理解分布式版本控制系統 2.遠程倉庫 3.新建遠程倉庫 4.克隆遠程倉庫 5.向遠程倉庫推送 6.拉取遠程倉庫 7.配置Git 7.1.忽略特殊文件 7.2.給命令配置別名 8.標簽管理 8.1.理解標簽 8.2.創建標簽 8.3.操作標簽 1.理解分布式版本控制系統 Git是目前世界上…

Vue3:component(組件:uniapp版本)

目錄 一、基本概述二、基本使用(父傳子)三、插槽四、子傳父 一、基本概述 在項目的開發過程中&#xff0c;頁面上井場會出現一些通用的內容&#xff0c;例如頭部的導航欄&#xff0c;如果我們每一個頁面都去寫一遍&#xff0c;那實在是太繁瑣了&#xff0c;所以&#xff0c;我…

C#語言實現PDF轉Excel

實現效果 第三方庫 ClosedXML iTextSharp 實現源碼 using System.Text; using iTextSharp.text.pdf; using iTextSharp.text.pdf.parser; using System.Text.RegularExpressions; using ClosedXML.Excel;namespace PdfToExcel_winform {public partial class MainForm : For…

如何將IDP映射屬性添加,到accountToken中 方便項目獲取登錄人信息

? 目標 你想要&#xff1a; 用戶通過 IdP 登錄&#xff08;SAML 或 OAuth2&#xff09;Keycloak 自動將 IdP 返回的屬性&#xff08;如&#xff1a;email、name、role 等&#xff09;映射到用戶賬戶中并把這些屬性加入到用戶登錄返回的 Access Token 中&#xff0c;供業務系…

JSON-RPC遠程控制

文章目錄 &#x1f310; 一、什么是 JSON-RPC&#xff1f;&#x1f4ec; 二、通信過程1?? 客戶端發起請求2?? 服務端處理請求&#xff0c;調用方法&#xff0c;返回結果 &#x1f4d1; 三、重要字段說明&#x1f6e0;? 四、核心函數與概念&#xff08;結合你的代碼&#x…

芝法醬躺平攻略(21)——kafka安裝和使用

本節內容比較初級&#xff0c;故接著躺平攻略寫 一、官網的下載 1.1 下載解壓 首先&#xff0c;去官網下載jar包&#xff0c;放進linux中&#xff0c;解壓到對應位置。 我的位置放在/WORK/MIDDLEWARE/kafka/4.0 1.2 常見配置 # 每個topic默認的分片數 num.properties4 # 數…

AutoSAR從概念到實踐系列之MCAL篇(二)——Mcu模塊配置及代碼詳解(上)

歡迎大家學習我的《AutoSAR從概念到實踐系列之MCAL篇》系列課程,我是分享人M哥,目前從事車載控制器的軟件開發及測試工作。 學習過程中如有任何疑問,可底下評論! 如果覺得文章內容在工作學習中有幫助到你,麻煩點贊收藏評論+關注走一波!感謝各位的支持! 根據上一篇內容中…

easypoi 實現word模板導出

特此非常致謝&#xff1a;easypoi實現word模板 基礎的可以參考上文&#xff1b; 但是我的需求有一點點不一樣。 這是我的模板&#xff1a;就是我的t.imgs 是個list 但是很難過的是easy poi 我弄了一天&#xff0c;我都沒有弄出來嵌套list循環怎么輸出顯示&#xff0c;更難過…

Unity中數據存儲_LitJson

文章目錄 LitJson一&#xff1a;介紹二&#xff1a;特點三&#xff1a;使用四&#xff1a;注意事項 LitJson 一&#xff1a;介紹 LitJson 是一個專為 .NET 設計的輕量級 JSON 處理庫&#xff0c;支持序列化和反序列化 JSON 數據。 二&#xff1a;特點 快速且輕量 無外部依賴…

2025年首屆人形機器人半程馬拉松比賽(附機器人照片)

2025年4月19日&#xff0c;北京亦莊半程馬拉松暨人形機器人半場馬拉松正式開賽&#xff0c;作為全球首屆人形機器人戶外跑步成功舉辦&#xff0c;21.0975公里的戶外路程對人形機器人來講&#xff0c;注定將成為歷史性開篇&#xff0c;如果賽事能夠持續舉辦&#xff0c;那舉辦意…

網絡安全職業技能大賽Server2003

通過本地PC中滲透測試平臺Kali對服務器場景Windows進?系統服務及版本掃描滲透測 試&#xff0c;并將該操作顯示結果中Telnet服務對應的端?號作為FLAG提交 使用nmap掃描發現目標靶機開放端口232疑似telnet直接進行連接測試成功 Flag&#xff1a;232 通過本地PC中滲透測試平臺…

[java八股文][Java基礎面試篇]I/O

Java怎么實現網絡IO高并發編程&#xff1f; 可以用 Java NIO &#xff0c;是一種同步非阻塞的I/O模型&#xff0c;也是I/O多路復用的基礎。 傳統的BIO里面socket.read()&#xff0c;如果TCP RecvBuffer里沒有數據&#xff0c;函數會一直阻塞&#xff0c;直到收到數據&#xf…

Python常用的第三方模塊之【jieba庫】支持三種分詞模式:精確模式、全模式和搜索引擎模式(提高召回率)

Jieba 是一個流行的中文分詞Python庫&#xff0c;它提供了三種分詞模式&#xff1a;精確模式、全模式和搜索引擎模式。精確模式嘗試將句子最精確地切分&#xff0c;適合文本分析&#xff1b;全模式則掃描文本中所有可能的詞語&#xff0c;速度快但存在冗余&#xff1b;搜索引擎…

QT6 源(37):界面組件的總基類 QWidget 的源碼閱讀(下,c++ 代碼部分)

&#xff08;1&#xff09; QT 在 c 的基礎上增加了自己的編譯器&#xff0c;以支持元對象系統和 UI 界面設計&#xff0c;有 MOC 、 UIC 等 QT 自己的編譯器。本節的源代碼里&#xff0c;為了減少篇幅&#xff0c;易于閱讀&#xff0c;去除了上篇中的屬性部分&#xff0c; 上篇…

rabbitmq-spring-boot-start版本優化升級

文章目錄 1.前言2.優化升級內容3.依賴4.使用4.1發送消息代碼示例4.2消費監聽代碼示例4.3 brock中的消息 5.RabbmitMq的MessageConverter消息轉換器5.1默認行為5.2JDK 序列化的缺點5.3使用 JSON 進行序列化 6.總結 1.前言 由于之前手寫了一個好用的rabbitmq-spring-boot-start啟…

git lfs下載大文件限額

起因是用 model.load_state_dict(torch.load())加載pt權重文件時&#xff0c;出現錯誤&#xff1a;_pickle.UnpicklingError: invalid load key, ‘v’. GPT告訴我&#xff1a;你的 pt 文件不是權重文件&#xff0c;而是模型整體保存&#xff08;或根本不是 PyTorch 文件&#…

什么是RAG?RAG的主要流程是什么?

**RAG(Retrieval-Augmented Generation)**是一種結合檢索與生成技術的框架,旨在通過引入外部知識增強生成模型的性能。其核心思想是:在生成文本時,先從外部知識庫中檢索相關信息,再將檢索結果與原始輸入結合,作為生成模型的輸入,從而提升生成內容的準確性、相關性和信息…

【Rust 精進之路之第13篇-生命周期·進階】省略規則與靜態生命周期 (`‘static`)

系列: Rust 精進之路:構建可靠、高效軟件的底層邏輯 作者: 碼覺客 發布日期: 2025年4月20日 引言:讓編譯器“讀懂”你的意圖——省略的藝術 在上一篇【生命周期入門】中,我們理解了生命周期的必要性——它是 Rust 編譯器用來確保引用有效性、防止懸垂引用的關鍵機制。我…

Python爬蟲實戰:獲取xie程網敦煌酒店數據并分析,為51出行做參考

一、引言 伴隨互聯網的飛速發展,在線旅游平臺成為人們出行預訂酒店的重要途徑。xie程網作為國內頗具知名度的在線旅游平臺,存有豐富的酒店信息。借助爬取xie程網的酒店數據并加以深入分析,能夠為用戶提供更為精準的酒店推薦,特別是在旅游旺季,如 51 出行期間。本研究致力…

第二十一講 XGBoost 回歸建模 + SHAP 可解釋性分析(利用R語言內置數據集)

下面我將使用 R 語言內置的 mtcars 數據集&#xff0c;模擬一個完整的 XGBoost 回歸建模 SHAP 可解釋性分析 實戰流程。我們將以預測汽車的油耗&#xff08;mpg&#xff09;為目標變量&#xff0c;構建 XGBoost 模型&#xff0c;并用 SHAP 來解釋模型輸出。 &#x1f697; 示例…