Vue.js 3 的设计思路
1. 声明式地描述UIVue.js 3是一个声明式UI框架编写前端页面涉及到以下内容1. DOM元素例如是div还是a标签。2. 属性乳a标签的href属性或idclass等通用属性。3. 事件如clickkeydown等。4. 元素的层级结构DOM树的层级结构既有子节点又有父节点。怎样声明式的描述上述内容Vue.js 3的解决方案是1. 使用与HTML标签一致的方式描述DOM元素如描述一个div标签时使用divdiv;2. 使用与HTML标签一致的方式描述属性如dividappdiv;3. 使用:或v-bind描述动态绑定的属性如div :iddynamicIddiv;4. 使用或v-on描述事件如div clickhandlerdiv;5. 使用与HTML标签一致的方式描述层级结构如一个具有span子节点的div标签divspanspandiv;可以看到每个内容都有与之对应的描述方式。用户不需要手写任何命令式代码。这就是声明式地描述UI。除了使用模板来声明式地描述UI外还可以javaScript对象来描述UIconst title{//标签名称 tag:h1, // 标签属性 props:{onclick: handler}, //子节点 children:[{tag:span}]}对应到Vue.js 模板h1 clickhandlerspan/span/h1使用javaScript对象描述UI比使用模板描述更灵活。letlevel3const title{tag:h${level }}可以看到当level 值改变时对应的标签名字也会在h1和h6之间变化。如果用模板描述则需要穷举h1 v-iflevel1/h1h2 v-iflevel2/h2h3 v-iflevel3/h3h4 v-iflevel4/h4h5 v-iflevel5/h5h6 v-iflevel6/h6使用javaScript对象描述UIde 方式就是虚拟DOM。在Vue.js组件中手写的渲染函数就是使用虚拟DOM来描述UI的。import{h}fromvueexportdefault{render(){retutn h(h1,{onClick: handler})//虚拟DOM}}h函数是一个辅助创建虚拟DOM的工具函数Vue.js会根据组件的render函数的返回值拿到虚拟DOM然后把组件内容渲染出来。虚拟DOM 就是用javaScript对象来描述真实的DOM 结构虚拟DOM本身就是一个javaScript对象没有特殊含义你完全可以自己设计虚拟DOM结构如使用tagName代替tag。2. 初识渲染器虚拟DOM怎样变为真实DOM并渲染到浏览器页面中呢这就是渲染器要做的工作将虚拟DOM渲染为真实DOM。声明一个虚拟DOMconst vnpde{tag:div, props:{onClick:()alert(hello)}, children:click me}编写一个渲染器将上面的虚拟DOM渲染为真实DOMfunctionrenderer(vnode,container){//使用vnode.tag作为标签名称床架DOM元素 const eldocument.createElement(vnode.tag)//遍历props将属性事件添加到DOM元素 for(const keyinvnode.props){if(/^on/.test(key)){//如果key以on开头说明它是事件 el.addEventListener(key.substr(2).toLowerCase(), //事件名称 onCleck---click vnode.props[key]//事件处理函数)}}//处理子节点 if(typeof vnode,childrenstring){//如果children 是字符串说明它是元素的文本子节点 el.appendChild(document.createTextNode(vnode.children))}elseif(Array,isArray(vnode.children)){//递归地调用renderer函数渲染子节点使用当前元素el作为挂载点 vnode.children.forEach(childrenderer(child,el))}//将元素添加到挂载下 container.appendChild(el)}renderer函数接收两个参数vnode虚拟DOM对象。container一个真实的DOM元素作为挂载点渲染器会把虚拟 DOM渲染到该挂载点下。渲染器renderer的实现思路1. 创建元素把vnodetag作为标签名称来创建DOM元素。2. 为元素添加属性和事件遍历vnode.props对象,如果key以on字符开头说明它是一个 事件把字符on截取掉后再调用toLowerCase函数将事件名称小写化最终得到合法的事件名称 例如onClick会变成click最后调用addEventListener绑定事件处理函数。4. 处理children如果children是一个数组就递归地调用renderer继续渲染注意此 时我们要把刚刚创建的元素作为挂载点父节点如果children是字符串。则使用 createTextNode函数创建一个文本节点并将其添加到新创建的元素内。这个渲染器函数仅做了创建节点的工作渲染器的精髓都在更新节点的阶段。对于渲染器来说它需要精确地找到vnode对象的变更点并且只更新变更的内容不需要再走一遍创建元素的流程。3. 组件的本质组件不是真实的DOM元素它是是一组DOM元素的封装这组DOM元素就是组件要渲染的内容因此我们可以用虚拟DOM来描述组件。因此可以定义一个函数来代表组件而函数返回值就代表组件要渲染的内容const MyComponentfunction(){return{tag:div, props:{onClick:()alert(hello)}, children:click me}}可以看到组件的返回值也是虚拟DOM它代表组件要渲染的内容。现在就可以用虚拟来描述组件了即让虚拟DOM对象中的tag属性来存储组件函数const vnode{tag: myComponent}此时tag: myComponent用来描述组件tag不再是标签名称而是组件函数未了支持渲染组件需要修改前面的renderer函数如下functionrenderer(vnode,container){if(typrof vnode,tagstring){//说明vnode描述的是标签元素 mountElement(vnode,container)}elseif(typeofvnode.tagfunction){//说明vnode描述的是组件 mountComponent(vnode,container)}}mountElement函数内容与rendere修改之前的内容完全一致functionmountElement(vnode,container){//使用vnode.tag作为标签名称床架DOM元素 const eldocument.createElement(vnode.tag)//遍历props将属性事件添加到DOM元素 for(const keyinvnode.props){if(/^on/.test(key)){//如果key以on开头说明它是事件 el.addEventListener(key.substr(2).toLowerCase(), //事件名称 onCleck---click vnode.props[key]//事件处理函数)}}//处理子节点 if(typeof vnode,childrenstring){//如果children 是字符串说明它是元素的文本子节点 el.appendChild(document.createTextNode(vnode.children))}elseif(Array,isArray(vnode.children)){//递归地调用renderer函数渲染子节点使用当前元素el作为挂载点 vnode.children.forEach(childrenderer(child,el))}//将元素添加到挂载下 container.appendChild(el)}mountComponent函数实现如下functionmountComponent(vnode,container){//调用组件函数获取组件要渲染的内容虚拟DOM const subtreevnode.tag()//递归调用renderer渲染subtree renderer(subtree,container)}可以看到首先调用vnode.tag函数返回虚拟DOM,这个虚拟DOM就是组件要渲染的内容我们称之为subtree既然subtree是虚拟DOM那么直接调用renderer函数完成渲染即可。组件不一定是函数形式的也可以用javaScript对象来表达组件//MyComponent 是一个对象 const MyComponent{render(){return{tag:div, props:{onClick:()alert(hello)}, children:click me}}}接着修改渲染器renderer和mountElement函数functionrenderer(vnode,container){if(typrof vnode,tagstring){//说明vnode描述的是标签元素 mountElement(vnode,container)}elseif(typeofvnode.tagobject){//如果是对象说明vnode描述的是组件 mountComponent(vnode,container)}}修改mountElement函数functionmountComponent(vnode,container){//vnode.tag是组件对象调用它的的render函数得到组件要渲染的内容虚拟DOM const subtreevnode.tag.render()//递归调用renderer渲染subtree renderer(subtree,container)}在上述代码中vnode.tag是表达组件的对象调用该对象的render函数得到组件要渲染的内容也就是虚拟DOM。4. 模板的工作原理模板的工作涉及到Vue.js框架中另一个重要的组成部分编译器。编译器和渲染器一样只是一段程序它的工作就是将模板编译为渲染函数。如一下模板div clickhandlerclick me/div对于编译器来说模板就是一个普通的字符串它会分析该字符串并生成一个功能与之相同的渲染函数render(){returnh(div,{onClick: handler},click me)}以.vue文件为例一个.vue文件就是一个组件如下所示templatediv clickhandlerclick me/div/templatescriptexportdefault{data(){/*... */}, methods:{handler:(){/*... */}}}/script其中标签里的内容就是模板内容编译器会把模板内容编译成渲染函数并添加到exportdefault{data(){/*... */}, methods:{handler:(){/*... */}},render(){returnh(div,{onClick: handler},click me)}}所以无论是使用模板还是手写渲染函数对于一个组件来说它要渲染的内容最终都是通过渲染函数产生的然后渲染器(renderer函数)再把渲染函数(render函数)返回的虚拟DOM渲染为真实的DOM这就是模板的工作原理也是Vue.js渲染页面的流程。5. Vue.js是由各个模块组成的有机整体组件的实现依赖于渲染器渲染器调用渲染函数生成虚拟DOM并最终把它变成屏幕上真实的DOM模板的编译依赖于编译器编译器将模板编译为渲染函数renderVue.js各个模块之间是相互关联互相制约的共同构成一个有机整体。下面以渲染器和编译器两个关键模块为例理解它们如何配合工作并实现性能提升。有以下模板dividfoo:classcls/div根据之前的介绍可知编译器会将这段代码编译为渲染函数render(){//为了效果更加直观这里没有使用h函数而是直接采用了虚拟DOM对象 //下面的代码等价于 //return h(div,{id:foo,class: cls})return{tag:div, props:{id:foo, class: cls}}}可以发现在这段代码中cls是一个变量它可能会发生变化。渲染器的工作之一是寻找并且只更新变化的内容。所以当cls值变化时渲染器会自动寻找变更点。这个“寻找”会花费一些力气。从编译器视角来看如果编译器有能力分析动态内容并在编译阶段将这些信息提取出来直接交给渲染器这样渲染器就不用寻找变更点了。Vue.js的实现方案如下以Vue.js模板来说它的模板是有特点的能一眼看出idfoo是静态数据永远不会变化:classcls是一个v-bind绑定它是会变化的。所以编译器能识别出哪些是静态属性哪些是动态属性在生成代码时完全可以附带这些信息render(){return{tag:div, props:{id:foo, class: cls}, patchFlag:1//假设数字1代表class是动态的}}虚拟DOM对象中多出一个patchFlag属性假设数字1代表class是动态的这样渲染器知道只有class属性会发生改变。对于渲染器来说相当于省去寻找变更点的工作量性能自燃就提升了。可以看到编译器和渲染器之间是存在信息交流的。它们互相配合使得性能进一步提升而它们之间交流的媒介就是虚拟DOM对象。虚拟DOM对象中会包含多种数据字段每个字段都代表一定的含义。6. 总结Vue.js是一个声明式框架声明式的好处在于它直接描述结果用户不关注过程。Vue.js采用模板的方式来描述UI,但它同样支持使用虚拟DOM来描述UI。虚拟DOM比模板更灵活模板比虚拟DOM更加直观。渲染器的作用是把虚拟DOM渲染为真实DOM元素。它的工作原理是递归地遍历虚拟DOM对象并调用原生DOM API来完成真实DOM元素的创建。渲染器的精髓在于更新它会通过Diff算法找出变更点并且只会更新需要更新的内容。组件是一组虚拟DOM元素的封装它可以是一个返回虚拟DOM的函数也可以是一个对象但这个对象下必须有一个函数用来产出组件要渲染的虚拟DOM渲染器在渲染组件时会现获取组件要渲染的内容即执行组件的渲染函数并得到其返回值虚拟DOM我们称之为subtree最后递归地调用渲染器将subtree渲染出来即可。Vue.js模板会被编译器的程序编译为渲染函数编译器渲染器都是Vue.js的核心组成部分它们共同构成一个有机整体不同模块之间互相配合进一步提升框架新能。

相关新闻

文字一键转学术可视化:paperxie 重构科研绘图全链路,消解学术作图多重内耗

文字一键转学术可视化:paperxie 重构科研绘图全链路,消解学术作图多重内耗

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/科研绘图科研绘图 - PaperXie智能写作PaperXie免费论文查重检测-首款免费论文检测软件,为毕业生提供专业的论文重复率检测、论文降重、Aigc检测、智能排版 、论文写作等一站式服务。https://www.paperxie.c…

2026/7/6 13:48:43 阅读更多 →
管理 Linux 联网

管理 Linux 联网

1.RHEL10 版本特点在 RHEL7 版本中,同时支持 network.service 和 NetworkManager.service(简称 NM)。在 RHEL8 上默认只能通过 NM 进行网络配置,包括动态 ip 和静态 ip,若不开启 NM,否则无法使用网络 RHEL8…

2026/7/6 13:46:41 阅读更多 →
【办公自动化小龙虾 AI】 OpenClaw 完整安装流程 报错与网关离线修复方案汇总(含安装包)

【办公自动化小龙虾 AI】 OpenClaw 完整安装流程 报错与网关离线修复方案汇总(含安装包)

OpenClaw 2.7.9 桌面 AI 自动化工具完整落地指南🦞|5 分钟搭建本地数字员工,告别繁杂环境配置 软件资源与设备适配📦 适配机型:Windows10/11 64 位、macOS 12 及以上全系列设备 稳定版本:OpenClaw 2.7.9 …

2026/7/6 13:40:35 阅读更多 →

最新新闻

无障碍设施开放公告增量采集,实战教学!

无障碍设施开放公告增量采集,实战教学!

㊗️本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~ ㊙️本期爬虫难度指数:⭐⭐⭐☆☆(进阶级) 🉐福利: 一次订阅后,专栏内的所有文章可永久免费看,持续更新中,保底1000+(篇)硬核实战内容。 全文目录: 🌟…

2026/7/6 14:33:27 阅读更多 →
视频号下载神器:3分钟搞定全网热门资源批量下载的终极指南

视频号下载神器:3分钟搞定全网热门资源批量下载的终极指南

视频号下载神器:3分钟搞定全网热门资源批量下载的终极指南 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 你是否…

2026/7/6 14:31:26 阅读更多 →
怎样判断一个技术人的认知在你之上:不是会说大词,而是这7个信号

怎样判断一个技术人的认知在你之上:不是会说大词,而是这7个信号

文章目录前言一、第一个信号:他先管理身体,而不是先喊意志力二、第二个信号:他遇到问题先找信息差,而不是急着表态三、第三个信号:他不跟你硬吵,因为他看到的是地基四、第四个信号:他情绪稳定&a…

2026/7/6 14:29:23 阅读更多 →
具身智能的定义、特征与原理解析(3)

具身智能的定义、特征与原理解析(3)

前沿技术介绍:AI智能体视觉(TVA,Transformer-based Vision Agent)是依托Transformer架构与“因式智能体”理论所构建的颠覆性工业视觉技术,属于“物理AI” 领域的一种全新技术形态,完成了从“虚拟世界”到“…

2026/7/6 14:29:23 阅读更多 →
宠物展会活动目录监控:用 Python 构建可复用的展会采集、时间序列化与 CSV 导出系统

宠物展会活动目录监控:用 Python 构建可复用的展会采集、时间序列化与 CSV 导出系统

㊗️本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~ ㊙️本期爬虫难度指数:⭐⭐⭐☆☆(进阶级) 🉐福利: 一次订阅后,专栏内的所有文章可永久免费看,持续更新中,保底1000+(篇)硬核实战内容。 全文目录: 🌟…

2026/7/6 14:27:22 阅读更多 →
机器学习与模式识别 第十八章 LLM的训练与应用 考点压缩

机器学习与模式识别 第十八章 LLM的训练与应用 考点压缩

第十八章:LLM Training and Applications — 知识点笔记综合来源:Lecture 18 PDF(44页)、课堂笔记(CSDN)占位图18.1 LLM完整推理流程 输入文本 → Tokenization → Embedding查表 → PE → Decoder Transf…

2026/7/6 14:27:22 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻