vue3源碼(六)渲染原理-runtime-dom

1、從入口文件看實現

項目入口文件

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'createApp(App).mount('#app')

文件位置core\packages\runtime-dom\src\index.ts
在這里插入圖片描述
保證了render唯一性

// // rendererOptions 是patchProp 和nodeOps的合集,包含了dom操作和節點對比方法
const rendererOptions = /*#__PURE__*/ extend({ patchProp }, nodeOps)function ensureRenderer() {return (renderer ||(renderer = createRenderer<Node, Element | ShadowRoot>(rendererOptions)))
}

createApp中主要調用了ensureRenderer創建返回的App,ensureRenderer中返回createRenderer
createRenderer核心方法baseCreateRenderer 主要包含了創建渲染器和更新和渲染的一系列方法,接下來開始從使用到實現吧~

2、兩種渲染器的使用

 import { createRenderer ,render,h} from "/node_modules/@vue/runtime-dom/dist/runtime-dom.esm-browser.js";// 1、createRenderer 我們可以自己創建渲染器(自己提供渲染方式)// 2、render 內置的渲染器 (渲染dom元素)// 3、h 方法可以創建一個虛擬dom (type,propsOrChildren,children)console.log(createRenderer,render,h);let  ele = h("h1","hello render")// render(ele,app)  用提供的api去渲染// 自定義渲染器const renderer = createRenderer({// 創建一個節點createElement(type){return document.createElement(type)},// 節點的展示setElementText(el,text){el.textContent = text},// 節點內容insert(el,container){container.appendChild(el)}})renderer.render(ele,app)// runtime-dom 提供一系列操作dom的API// @vue/runtime-dom是針對瀏覽器的  --> @vue/runtime-core 是跨平臺的  --> @vue/reactivity 

3、renderOptions實現

renderOptions主要包含兩個部分:

  • dom節點的操作
  • 屬性的操作
const renderOptions = Object.assign({ patchProp }, nodeOps);
export { renderOptions };

3.1 nodeOps

export const nodeOps = {insert: (child, parent, anchor) => {// 添加節點parent.insertBefore(child, anchor || null);},remove: (child) => {// 節點刪除const parent = child.parentNode;parent && parent.removeChild(child);},createElement: (tag) => document.createElement(tag), // 創建節點createText: (text) => document.createTextNode(text), // 創建文本setText: (node, text) => (node.nodeValue = text), //  設置文本節點內容setElementText: (el, text) => (el.textContent = text), // 設置文本元素中的內容parentNode: (node) => node.parentNode, // 父親節點nextSibling: (node) => node.nextSibling, // 下一個節點querySelector: (selector) => document.querySelector(selector), // 搜索元素
};

3.2 patchProp

export default function patchProp(el, key, prevValue, nextValue) {if (key === "class") {return patchClass(el, nextValue);} else if (key === "style") {return patchStyle(el, prevValue, nextValue);} else if (/^on[^a-z]/.test(key)) {return patchEvent(el, key, nextValue);}else{return patchAttr(el, key, nextValue)}
}

3.2.1 patchClass

export default function patchClass(el, value) {if (value) {el.className = value;} else {el.removeAttribute("class");}
}

3.2.2 patchStyle

export default function patchStyle(el, prevValue, nextValue) {let style = el.style;// 把新的加進來for (let key in nextValue) {style[key] = nextValue[key];}// 把多余的刪掉if (prevValue) {for (let key in prevValue) {if (nextValue[key] == null) {style[key] = null;}}}
}

3.2.3 patchEvent

// 創建一個調用器,執行value值,value可以改變
function createInvoker(value) {const invoker = (e) => invoker.value();invoker.value = value; // 修改value可以修改方法對應的調用函數return invoker;
}export default function patchEvent(el, name, nextValue) {const invokers = el._vei || (el._vei = {});const eventName = name.slice(2).toLowerCase();const existingInvoker = invokers[name];//   如果之前存在同名方法 則修改函數if (nextValue && existingInvoker) {return (existingInvoker.value = nextValue);}if (nextValue) {// 如果之前沒有同名方法, 則給方法賦值const invoker = (invokers[name] = createInvoker(nextValue));return el.addEventListener(eventName, invoker);}if (existingInvoker && !nextValue) {el.removeEventListener(eventName);invokers[name] = undefined;}
}

3.2.4 patchAttr

export default function patchAttr(el,key, value) {if (value) {el.setAttribute(key, value);} else {el.removeAttribute(key)}
}

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

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

相關文章

可視化低代碼平臺之:RayData光啟元的震撼作品。

RayData家的可視化作品&#xff0c;貝格前端工場是經常碰到&#xff0c;制作十分的精良&#xff0c;業內很有影響力。他們也有自己的低代碼平臺&#xff0c;分為了桌面版和網頁版&#xff0c;本期分享一下他們的作品。

徹底掌握 Git:從零基礎到高級實戰的全方位教程

文章目錄 一、Git 簡介二、安裝 Git1. Windows2. macOS3. Linux 三、Git 基本概念四、初次使用 Git1. 配置 Git2. 創建一個新的 Git 倉庫3. 克隆一個遠程倉庫4. 跟蹤文件5. 提交變更6. 查看歷史記錄 五、Git 分支管理1. 創建和切換分支2. 合并分支3. 分支沖突 六、遠程倉庫1. 添…

to_json 出現亂碼的解決方案

大家好,我是愛編程的喵喵。雙985碩士畢業,現擔任全棧工程師一職,熱衷于將數據思維應用到工作與生活中。從事機器學習以及相關的前后端開發工作。曾在阿里云、科大訊飛、CCF等比賽獲得多次Top名次。現為CSDN博客專家、人工智能領域優質創作者。喜歡通過博客創作的方式對所學的…

國產分布式數據庫災備高可用實現

最近在進行核心業務系統的切換演練測試&#xff0c;就在想一個最佳的分布式數據庫高可用部署方案是如何保證數據不丟、系統可用的&#xff0c;做到故障時候可切換、可回切&#xff0c;并且業務數據的一致性。本文簡要介紹了OceanBase數據庫和GoldenDB數據庫在災備高可用的部署方…

kafka的架構

一、架構圖 Broker&#xff1a;一臺 kafka 服務器就是一個 broker。一個kakfa集群由多個 broker 組成。一個 broker 可以容納多個 topic。 Producer&#xff1a;消息生產者&#xff0c;就是向 kafka broker 發消息的客戶端 Consumer&#xff1a;消息消費者&#xff0c;向 kafk…

深海電波,智能駕馭:海上發電系統中的先進網關技術

隨著技術的不斷演進&#xff0c;海上風電場逐漸走向深海&#xff0c;隨之而來的高速通信保障成為一大難題。同時&#xff0c;海上風電特殊的環境與部署技術&#xff0c;也給運維帶來了作業難、成本高、響應慢等困難。通過在沿海岸邊建立高站&#xff0c;結合超遠覆蓋、載波聚合…

springboot java.lang.ClassNotFoundException: dm.jdbc.driver.DmDriver 應該如何解決

遇到的問題&#xff1a;項目中引用了外部的達夢jar包 在idea中正常使用 也能找到dm.jdbc.driver.DmDriver 驅動 但是當通過jenkins 構建部署到服務器上 總是報 ClassNotFoundException: dm.jdbc.driver.DmDriver 找不到驅動 應用到的驅動代碼如下格式 排查步驟 1.首先看你的項…

ROS2仿真工具-gazebo

gazebo獨立于ROS2&#xff0c;就像插件一樣&#xff0c;需要安裝。 1.安裝 sudo apt install gazebo sudo apt install ros-humble-gazebo-* 2.運行測試demo gazebo /opt/ros/humble/share/gazebo_plugins/worlds/gazebo_ros_diff_drive_demo.world 查看所有話題 ros2 top…

0052__windows下實現socketpair函數

windows下實現socketpair函數_socketpair windows 實現-CSDN博客 socketpair函數介紹及使用-CSDN博客

使用css做一個旋轉的八卦圖

使用css做一個旋轉的八卦圖 1, html部分 <div class"tai"><div class"bai"></div><div class"hei"></div> </div>2, css部分 .tai{width: 200px;height: 200px;border: 1px solid #000;background: linea…

工業路由器的應用

上文講了工業路由器與家用路由器的區別, 家用路由器的使用場景想必大家都不陌生&#xff0c;那么工業路由器可以具體應用在哪些領域呢&#xff1f; 工業路由器憑借其多接口、多協議、寬溫寬壓等工業設計特性&#xff0c;可以廣泛應用于各類工業化場景&#xff0c;為各類工業傳…

STM32中的I2S(Inter-IC Sound)接口和SA接口(Serial Audio Interface)的區別

STM32中的I2S&#xff08;Inter-IC Sound&#xff09;接口和SA接口&#xff08;這里的SA可能指的是SAI&#xff0c;Serial Audio Interface&#xff09;雖然都用于音頻數據傳輸&#xff0c;但它們在設計目標、功能特性和應用場景上存在一些區別&#xff1a; I2S (Inter-IC Sou…

STM32-I2C硬件外設

本博文建議與我上一篇I2C 通信協議??????共同理解 合成一套關于I2C軟硬件體系 STM32內部集成了硬件I2C收發電路&#xff0c;可以由硬件自動執行時鐘生成、起始終止條件生成、應答位收發、數據收發等功能&#xff0c;減輕CPU的負擔 特點&#xff1a; 多主機功能&#x…

Shiro框架

入門概述 1 shiro是什么? Apache Shiro 是一個功能強大且易于使用的 Java 安全(權限)框架。Shiro 可以完成&#xff1a;認證、授權、加密、會話管理、與 Web 集成、緩存 等。借助 Shiro 您可以快速輕松地保護任何應用程序——從最小的移動應用程序到最大的 Web 和企業應用程…

計算機網絡網絡層復習題1

一. 單選題&#xff08;共27題&#xff09; 1. (單選題)以太網 MAC 地址、IPv4 地址、IPv6 地址的地址空間大小分別是&#xff08; &#xff09;。 A. 2^48&#xff0c;2^32&#xff0c;2^128B. 2^32&#xff0c;2^32&#xff0c;2^96C. 2^16&#xff0c;2^56&#xff0c;2^6…

選對箱式壓風自救裝置提升煤礦生產效率

選對箱式壓風自救裝置提升煤礦生產效率&#xff0c;安全是煤礦穩定生產的基石&#xff0c;只有始終保持對安全的敬畏之心&#xff0c;才能確保礦區可持續發展和經濟效益的穩步提升。 150簡介 ZYJ-A型礦井壓風自救裝置是煤礦煤塵、瓦斯和二氧化碳突出礦井的實際情況&#xff0c…

淺談k8s中cni0和docker0的關系和區別

最近在復習k8s網絡方面的知識&#xff0c;查看之前學習時整理的筆記和文檔還有過往自己總結的博客之后發現一個問題&#xff0c;就是在有關flannel和calico這兩個k8s網絡插件的文章和博客中&#xff0c;會涉及到cni0和docker0這兩個網橋設備&#xff0c;但是都沒有明確說明他們…

C# WPF自制批注工具(方便標記重點和演示)

在教學和演示中&#xff0c;我們通常需要對重點進行批注&#xff0c;下載安裝第三方工具批注顯得很麻煩。本篇使用WPF開發了一個批注工具&#xff0c;工具小巧&#xff0c;功能豐富&#xff0c;非常使用日常免費使用&#xff0c;或者進行再次開發。 自制批注工具具有以下功能特…

AUTOSAR NvM模塊(五)

NvMRbCallbackSignatureAR45 改變回調函數的參數類型。 TRUE&#xff1a;根據AR44及之后版本&#xff0c;回調函數使用NvM_<Multi;Init>BlockRequestType參數類型。詳細的函數調用參數請參考回調參數。 FALSE&#xff1a;根據AR43及之前版本&#xff0c;回調函數使用S…

GPT-5 一年半后發布,對此你有何期待?

CHATGPT5&#xff1a;未來一年內的期待與挑戰 隨著人工智能技術的飛速發展&#xff0c;自然語言處理&#xff08;NLP&#xff09;領域的突破不斷涌現。在這一背景下&#xff0c;CHATGPT系列模型作為NLP領域的佼佼者&#xff0c;其每一次的更新都牽動著業界的目光。當得知CHATG…