Vue 3的核心機制-解析事件流、DOM更新、數據請求、DOM操作規范及組件庫DOM操作的解決方案

文章目錄

    • 概要
    • 整體介紹
    • vue 中dom操作推薦方案實例

概要

從Vue 3的核心機制出發,結合場景、應用與實例,系統化解析事件流、DOM更新、數據請求、DOM操作規范及組件庫DOM操作的解決方案:

整體介紹

?? 一、事件流處理機制

  1. 核心機制
    ? 三個階段:捕獲(從根節點向目標傳遞) → 目標(觸發目標元素) → 冒泡(從目標向根節點回溯)。

    ? Vue封裝:默認在冒泡階段處理事件,可通過 .capture 修飾符切換至捕獲階段。

  2. 應用場景與實例
    ? 阻止冒泡:使用 @click.stop 替代原生 event.stopPropagation()。

 <div @click="parentClick"><button @click.stop="childClick">點擊不觸發父級</button></div>

? 事件委托優化:在父級監聽子組件事件,通過 event.target 過濾目標。

? 自定義事件:子組件 $emit(‘update’, data),父組件 @update=“handler” 實現跨組件通信。

🔄 二、DOM更新原則

  1. 響應式驅動更新
    ? Proxy代理:數據變更 → 觸發依賴追蹤 → 重新渲染虛擬DOM → Diff算法比對 → 精準更新真實DOM。

    ? 批量更新:多次數據修改合并為單次渲染(nextTick 機制)。

  2. 性能優化策略
    ? Patch Flags標記:動態節點添加標志(如 CLASS、STYLE),僅更新變化的屬性。

    ? Key的作用:列表渲染時,key 幫助Diff算法識別節點身份,避免不必要的重建。

<li v-for="item in list" :key="item.id">{{ item.name }}</li>

📡 三、數據請求原則

  1. 最佳實踐
    ? 生命周期掛鉤:在 onMounted 中發起請求,避免SSR兼容問題。

    ? 響應式綁定:數據存儲于 ref/reactive,自動觸發視圖更新。

const data = ref([]);onMounted(async () => {data.value = await axios.get('/api/data');});

? 防抖/節流:高頻請求(如搜索框)使用 lodash.debounce 優化。

  1. 狀態管理整合
    ? Pinia/Vuex:跨組件共享請求數據,通過 actions 封裝異步邏輯。

?? 四、Vue的DOM操作 vs 直接DOM操作

方式 Vue推薦方式 直接操作DOM的風險
獲取DOM ref 綁定模板引用:

document.querySelector 破壞組件封裝性
修改屬性 數據驅動::class=“{ active }” el.className = ‘active’ 繞過響應式系統
動態結構 v-if/v-for 控制渲染 innerHTML 可能導致XSS漏洞

典型影響:
? 響應式失效:直接修改DOM不會更新Vue數據狀態,導致數據與視圖不一致。

? 性能下降:手動DOM操作可能觸發多次重繪,抵消虛擬DOM的批量更新優勢。

🧩 五、組件庫中DOM操作的解決方案

  1. 問題根源
    組件庫(如Element Plus)封裝內部DOM結構,外部無法直接訪問子組件DOM節點。

  2. 解決方案
    ? Ref暴露:組件庫通過 ref 暴露內部元素(需文檔支持)

<el-input ref="inputRef" />  
setup() {  const inputRef = ref(null);  onMounted(() => inputRef.value?.focus());  
} 

? 插槽占位:使用插槽插入自定義內容并操作

 <el-dialog>  <div ref="dialogContent">自定義內容</div>  </el-dialog>

? 生命周期鉤子:庫組件提供 @opened 等事件,在適當時機操作DOM。

? Teleport組件:將內容渲染到外部容器(如全局彈窗),繞過組件層級。

💎 總結

Vue 3通過響應式驅動、虛擬DOM優化、事件系統封裝構建高效開發范式。
? 規避直接DOM操作:優先使用數據驅動和 ref 接口。

? 組件庫協作:善用暴露的API、插槽和生命周期事件,避免穿透組件邊界。

? 性能關鍵:Diff算法與批量更新機制是高效渲染的核心,理解其原理可避免性能陷阱。

vue 中dom操作推薦方案實例

在 Vue 3 中監聽 Ant Design Vue(AntDV)的 Table 組件滾動事件時,應優先使用 Vue 的響應式 API 和組件實例引用(ref)而非直接操作原生 DOM。以下是幾種推薦方案及其實現方法:

🔍 1. 通過 ref 獲取組件實例,再定位內部 DOM

原理:通過 ref 獲取 Table 組件實例,再通過其 $el 屬性訪問根 DOM 元素,進一步用 querySelector 定位滾動容器(如 .ant-table-body)。
適用場景:需精確監聽滾動容器(如表體)的滾動事件。
實現步驟:

<template><a-table ref="tableRef" :data-source="data" :columns="columns" /></template><script setup>import { ref, onMounted, onBeforeUnmount } from 'vue';const tableRef = ref(null);let scrollContainer = null;const handleScroll = (e) => {console.log('滾動位置:', e.target.scrollTop);};onMounted(() => {if (tableRef.value) {// 獲取 Table 內部的滾動容器scrollContainer = tableRef.value.$el.querySelector('.ant-table-body');if (scrollContainer) {scrollContainer.addEventListener('scroll', handleScroll);}}});onBeforeUnmount(() => {if (scrollContainer) {scrollContainer.removeEventListener('scroll', handleScroll);}});</script>

注意:
? 需手動管理事件監聽器的綁定與銷毀,避免內存泄漏。

? AntDV 的滾動容器類名(如 .ant-table-body)可能隨版本變化,需驗證兼容性。

🎯 2. 直接使用 Table 組件的 @scroll 事件

原理:部分組件庫為 Table 內置了 scroll 事件(需查閱文檔確認支持性)。
適用場景:組件庫已封裝滾動事件時,代碼更簡潔。
實現步驟:

   <template><a-table @scroll="handleScroll" :data-source="data" :columns="columns" /></template><script setup>const handleScroll = (e) => {// e.target 為觸發滾動的 DOM 元素console.log('滾動事件:', e);};</script>

注意:
? AntDV 官方文檔未明確說明 @scroll 事件支持,實際測試發現部分版本可能生效。

? 若事件未觸發,需回退到方案 1。

?? 3. 結合 ref 與生命周期鉤子優化

增強點:利用 nextTick 確保 DOM 渲染完成后再操作。
適用場景:動態數據加載后需操作滾動條(如滾動到底部)。
實現步驟:

<script setup>
import { nextTick } from 'vue';// 數據加載后滾動到底部const loadData = async () => {data.value = await fetchData();nextTick(() => {const container = tableRef.value?.$el.querySelector('.ant-table-body');if (container) {container.scrollTop = container.scrollHeight;}});};</script>

💎 方案對比與選擇建議

方案 優點 缺點 適用場景

ref + 查詢內部 DOM 精準控制滾動容器,兼容性強 需手動管理事件,依賴內部類名 需監聽具體滾動容器

組件內置 @scroll 事件 代碼簡潔,符合 Vue 事件綁定規范 依賴組件庫支持,可能不穩定 快速實現,兼容版本可用時

生命周期鉤子優化 確保 DOM 更新后操作,避免空引用 需結合其他方案使用 動態數據加載后滾動定位

?? 關鍵注意事項

  1. 避免直接操作 DOM
    Vue 的響應式設計優先通過數據驅動視圖,直接操作 DOM(如 document.querySelector)會破壞封裝性,導致與 Vue 的更新機制沖突。

  2. 組件庫的封裝限制
    AntDV 等組件庫的內部 DOM 結構是黑盒,更新版本可能調整類名或結構。若必須操作內部 DOM,需在代碼中增加兼容性處理。

  3. 使用 defineExpose 暴露子組件方法
    若需調用 Table 組件的內部方法(如滾動到指定行),可要求子組件通過 defineExpose 暴露方法,父組件通過 ref 調用:

   <!-- 子組件 --><script setup>defineExpose({ scrollToRow: (index) => { ... } });</script><!-- 父組件 --><script setup>const tableRef = ref(null);tableRef.value?.scrollToRow(10);</script>

💎 總結

優先使用 Vue 的 ref 獲取組件實例,再通過其 $el 定位滾動容器,是平衡 Vue 響應式原則 與 操作 DOM 需求 的最佳實踐。若組件庫支持內置事件(如 @scroll),可進一步簡化代碼。務必在生命周期鉤子中管理事件監聽,并避免直接操作原生 DOM 以維護應用穩定性。

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

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

相關文章

Python從入門到高手9.2節-Python字典的操作方法

目錄 9.2.1 字典的操作 9.2.2 字典的查找 9.2.3 字典的修改 9.2.4 字典的添加 9.2.5 字典的刪除 9.2.6 今天你逛街了嗎 9.2.1 字典的操作 字典類型是一種抽象數據類型&#xff0c;抽象數據類型定義了數據類型的操作方法&#xff0c;在本節的內容中&#xff0c;教同學們徹…

omniparser v2 本地部署及制作docker鏡像(20250715)

關于 omniparser v2 本地部署&#xff0c;網上資料不算多&#xff0c;尤其是對于土薔內用戶&#xff0c;還是有些坑的。 1、安裝步驟 可參考兩個CSDN博客&#xff1a; &#xff08;1&#xff09;大模型實戰 - ‘OmniParser-V2本地部署安裝 鏈接 &#xff08;2&#xff09;…

自己寫個 `rsync` + `fswatch` 實時增量同步腳本,干掉 Cursor AI、Sublime Text 的SFTP等 插件!

自己寫個 rsync fswatch 實時增量同步腳本&#xff0c;干掉 Cursor AI、Sublime Text 的 SFTP等 插件&#xff01; 作為一個碼農&#xff0c;我最頭疼的事情之一就是編輯器同步代碼到服務器這塊。用過各種各樣的sftp、rsync插件&#xff0c;感覺不好用。。 我琢磨著&#xff1…

linux中at命令的常用用法。

Linux 中 at 命令用于安排一次性定時任務&#xff0c;需要用到在某個時間只需要執行一次的命令的時候&#xff0c;可以使用at 1&#xff1a;安裝at # Debian/Ubuntu sudo apt install at# CentOS/RHEL sudo yum install at2&#xff1a;啟動at sudo systemctl start atd # 啟…

【安卓筆記】RxJava的使用+修改功能+搭配retrofit+RxView防快速點擊

0. 環境&#xff1a; 電腦&#xff1a;Windows10 Android Studio: 2024.3.2 編程語言: Java Gradle version&#xff1a;8.11.1 Compile Sdk Version&#xff1a;35 Java 版本&#xff1a;Java11 1. 介紹RxJava GitHub開源地址&#xff1a;https://github.com/Reactive…

Windows 下原生使用 claude code + Kimi K2

搞定了kimi k2 claude code在windows下原生使用 Windows下使用claude code的障礙是shell環境&#xff08;命令行&#xff09;&#xff0c;非posix風格shell無法正常讓claude code讀取到url和key, 導致無法使用。解決問題的本質是使用符合posix風格的shell環境&#xff0c;我們…

Leetcode Easy題小解(C++語言描述)1

Leetcode Easy題小解&#xff08;C語言描述&#xff09; 相交鏈表 給你兩個單鏈表的頭節點 headA 和 headB &#xff0c;請你找出并返回兩個單鏈表相交的起始節點。如果兩個鏈表不存在相交節點&#xff0c;返回 null 。 圖示兩個鏈表在節點 c1 開始相交**&#xff1a;**題目數據…

EP01:【NLP 第二彈】自然語言處理概述

一、NLP通向智能之路 1.1 圖靈測試 1.1.1 提出背景 由計算機科學家阿蘭?圖靈于 1950 年提出&#xff0c;是早期衡量機器智能水平的重要概念。 1.1.2 提出目的 判斷機器是否能表現出與人類相當的智能行為。 1.1.3 測試原理 場景設定&#xff1a;測試中存在一位人類測試者&#…

Ansible 查看PostgreSQL的版本

Ansible的基礎知識就不說了直接貼劇本- name: Check PostgreSQL versionhosts: db_serversbecome: yesvars:ansible_python_interpreter: /usr/bin/python3db_name: postgresdb_user: postgresdb_password: your_passwordtasks:- name: Install psycopg2ansible.builtin.packag…

【視覺SLAM筆記】第9章 后端1

一、理論1. 狀態估計的概率解釋我們來深入探討一下視覺SLAM中狀態估計的概率解釋。這可以說是理解現代SLAM算法&#xff08;尤其是后端優化&#xff09;的基石1. 問題的核心&#xff1a;不確定性SLAM&#xff08;同步定位與建圖&#xff09;的本質是在一個未知環境中&#xff0…

(數據結構)復雜度

基本概念說明 數據結構 定義&#xff1a;數據結構(Data Structure)是計算機存儲、組織數據的方式&#xff0c;指相互之間存在?種或多種特定關系的數據元素的集合。沒有?種單?的數據結構對所有用途都有用&#xff08;要考慮適配、效率問題&#xff0c;在不同情況下使用合適的…

玩轉Docker | 使用Docker部署bender個人導航頁工具

玩轉Docker | 使用Docker部署bender個人導航頁工具 前言 一、bender介紹 Bender 簡介 Bender 的主要特點 二、系統要求 環境要求 環境檢查 Docker版本檢查 檢查操作系統版本 三、部署bender服務 下載bender鏡像 編輯部署文件 創建容器 檢查容器狀態 檢查服務端口 安全設置 四、…

解決了困擾我的upload靶場無法解析phtml等后綴的問題

本文章為解決困擾我的 upload 靶場無法解析 phtml 問題 ? 這個問題直接讓我過不了Upload-Pass-03這一關&#xff0c;一直卡著。 ? 痛太痛了 &#xff0c;為什么無法解析上傳之后的 phtml 后綴文件&#xff01;這塊兒折磨了博主一天多&#xff0c;太不容易了&#xff0c;查找…

Leetcode百題斬-二分搜索

二分搜索也是一個很有趣的專題&#xff0c;被做過的題中&#xff0c;剛好一個Easy&#xff0c;一個Medium和一個Hard&#xff0c;剛好可以看看&#xff0c;二分搜索的三個難度等級都是啥樣的。 124. Binary Tree Maximum Path Sum[Hard]&#xff08;詳見二叉樹專題&#xff09;…

【IDEA】格式化代碼工具配置

格式化代碼快捷鍵&#xff1a; CtrlAltL格式代碼的時候不會再方法名與參數中間添加空格默認不勾選的情況下&#xff1a;代碼樣例&#xff1a;勾選之后的樣例&#xff1a;選擇不勾選&#xff0c;IDEA默認情況下就是不勾選的狀態忽略加載文件有些非必要加載到開發工具中的文件我們…

驅動開發(3)|rk356x驅動GPIO基礎應用之點亮led燈

點亮LED燈看似是一個基礎的操作&#xff0c;但實際上&#xff0c;許多高級應用也依賴于高低電平的切換。例如&#xff0c;脈沖寬度調制&#xff08;PWM&#xff09;信號可以用來精確控制電機的轉速&#xff0c;通過改變脈沖的頻率和占空比&#xff0c;實現對電機的精確調節&…

手動搭建PHP環境:步步為營,解鎖Web開發

目錄一、引言二、準備工作2.1 明確所需軟件2.2 下載軟件三、Windows 系統搭建步驟3.1 安裝 Apache 服務器3.2 安裝 PHP3.3 集成 Apache 與 PHP3.4 安裝 MySQL3.5 配置 PHP 連接 MySQL四、Linux 系統搭建步驟&#xff08;以 Ubuntu 為例&#xff09;4.1 更新系統4.2 安裝 Apache…

DrissionPage:一款讓網頁自動化更簡單的 Python 庫

在網頁自動化領域&#xff0c;Selenium 和 Playwright 早已是開發者耳熟能詳的工具。但今天要給大家介紹一款更輕量、更易用的 Python 庫 ——DrissionPage。它以 "融合 selenium 和 requests 優勢" 為核心設計理念&#xff0c;既能像 requests 一樣高效處理靜態網頁…

理解Grafana中`X-Scope-OrgID`的作用與配置

X-Scope-OrgID的作用 該HTTP Header用于標識Loki日志數據的所屬租戶&#xff08;組織&#xff09;。在多租戶模式下&#xff0c;Loki通過此Header隔離不同團隊或用戶的數據&#xff0c;確保查詢和存儲的獨立性。數據隔離&#xff1a; 租戶A的日志標記為X-Scope-OrgID: team-a&a…

【PycharmPyqt designer桌面程序設計】

在 main.py 中調用 Qt Designer 生成的 windows.py&#xff08;假設它是 PySide2 版&#xff09;。 只要把兩個文件放在同一目錄即可直接運行。 ──────────────────── 1?? windows.py&#xff08;Qt Designer 生成&#xff0c;已轉碼&#xff09; # -*-…