vue深入理解(1)

news2025/1/16 23:24:09

本文章内容主要来源于《vue.js设计与实现》

视图层框架设计

命令式和声明式

范式上,视图层框架通常分为命令式和范式

JQuery就是典型的命令式框架,命令式框架的一大特点就是关注过程

例子:

$('#app') // 获取app
	.text('hello world') // 设置文本内容
	.on('click', () => { alert('ok') })

原生JS实现例子:

const div = document.querySelector('#app')
div.innerText = 'hello world'
div.addEventListener('click', () => { alert('ok') })

声明式框架更加关注结果

vue.js例子:

<div @click="() => alert('ok')">
  hello world
</div>

可以看出在vue.js实现就是提供的是一个“结果”,怎么去实现的这个过程我们并不关心这是由vue.js帮我们完成的

也就是Vue封装了这个过程

  • vue的内部实现一定是命令式的,而暴露给用户的则更加声明式

两者性能与可维护性比较

命令式代码的性能优于声明式的性能

若要实现修改文本内容如上面代码,只需要直接调用相关命令即可

div.innerText = 'nihao'

理论上命令式代码可以做到极致的代码优化(因为明确知道哪些发生更改,只需要做必要的修改

对于框架而言,为了实现最优的更新性能,需要找到前后差异并只更新变化的地方

把直接修改消耗的性能定义为A,把找出差异的性能消耗定义为B

  • 命令式代码的更新性能消耗=A
  • 声明式代码的更新性能消耗=B + A

声明式代码的可维护性更强(命令式代码需要维护实现目标的整个过程)

虚拟DOM性能

该部分主要是初步介绍虚拟DOM,主要讲述weishe

由于声明式代码的更新性能消耗=B + A

为了最小化找出差异的性能消耗,所以让声明式代码的性能无限接近于命令式消耗 -------- 虚拟DOM就是为了最小化找出差异这一步的性能消耗

理论上采用虚拟DOM的更新技术的性能不可能比原生JS操作DOM更高

虚拟DOM在vue中使用就是为了写声明式代码,还能够保证应用程序的性能下限

以上说的原生JS指的是类似于document.creatElement之类的DOM操作,并不包含innerHTML

innerHTML操作页面

使用innerHTML创建页面需要构建一段HTML字符串,然后将字符串赋值给DOM元素的innerHTML属性

  • 但深层并非这句话这么简单,为了渲染出页面,首先要把字符串解析成DOM树(这是一个DOM层面的计算

涉及DOM的计算要远比JS层面的计算性能差,纯JS层面的操作比DOM操作快得多,甚至不在一个数量级

请添加图片描述

使用innerHTML更新页面的过程是重新构建HTML字符串,再重新设置DOM元素的innerHTML属性(相当于销毁所有旧的DOM元素,再 全量 创建新的DOM元素

虚拟DOM操作页面

使用虚拟DOM创建页面首先创建JS对象(该对象为真实DOM的映照),然后递归地遍历DOM树并创建真实DOM

使用虚拟DOM更新页面需要重新创建虚拟DOM树,然后比较新旧虚拟DOM,找到变化地元素并更新它

两者相比

虚拟DOM在 JS层面的计算 要比创建页面是多出一个Diff的性能消耗,但不会产生数量级的差异 ;然后DOM层面的计算,虚拟DOM在更新页面时只会更新必要的元素,但innerHTML要全量更新

性能总结

请添加图片描述

运行时、编译时

编译时(Compile Time)和运行时(Runtime)指的是程序在不同的阶段进行的不同类型的处理。

js 编译是什么呢?
现代前端开发,我们都是使用 react、vue、webpack 等工具,其实就是把这些框架代码编译成了 js 代码,那么编译时其实是指的,webpack 等工具把 react、vue 编译为 js 的过程。运行时自然不用说,就是浏览器解释 js 代码的过程。

纯运行时框架例子

// 渲染 dom
function render (node, root) {
  const el = document.createElement(node.tag)
  if (typeof node.children === 'string') {
    const text = document.createTextNode(node.children)
    el.appendChild(text)
  }
  if (Array.isArray(node.children)) {
    node.children.forEach(child => render(child, el)) // 递归地处理节点的渲染
  }
  root.appendChild(el)
}

const node = {
  tag: 'div', // tag代表标签名称
  children: [ // children可以是一个数组,代表子节点
    {
      tag: 'h1',
      children: 'hello' // children也可以是一段文本,代表文本子节点
    }
  ]
}

render(node, document.body)

用户在使用render函数渲染内容时,直接为render函数提供了一个树型结构的数据对象

但若是用户需求是手写树型结构的数据对象太麻烦了,而且不直观,想要支持用类似HTML的方式描述树型结构的数据对象,所以引入编译的手段,把HTML标签编译成树型结构的数据对象

纯编译时框架例子

<div>
  <h1>hello</h1>
</div>

经过编译

const div = document.createElement('div')
const h1 = document.createElement('h1')
h1.innerText = 'hello'
div.appendChild(h1)
document.body.appendChild(div)

直接将HTML字符串编译成命令式代码过程

编译时+运行时框架例子

编写一个Compiler的程序,作用是把HTML字符串编译成树型结构的数据对象

const html = '
<div>
  <span>hello</span>
</div>
'
// 调用Compiler编译得到树形结构的数据对象
const obj = Compiler(html)
// 再调用render进行渲染
render(obj, document.bod)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2256389.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSDN博客如何修改删除上传的资源

CSDN博客是我用过的最好用的博客&#xff0c;它对用户发布文章的限制比较少&#xff0c;而且还支持用户利用知识创新来获取收益&#xff0c;不象51CTO这种垃圾博客&#xff0c;动不动就给扣分限号。但我发现CSDN也有设计缺陷&#xff0c;虽然其上传资源的入口很好找&#xff0c…

【SpringBoot】Day11-10 yml文件配置

三种配置文件 前面我们一直使用springboot项目创建完毕后自带的application.properties进行属性的配置&#xff0c;那其实呢&#xff0c;在springboot项目当中是支持多种配置方式的&#xff0c;除了支持properties配置文件以外&#xff0c;还支持另外一种类型的配置文件&#x…

React路由使用入门react-router-dom

1.安装react-router-dom npm i react-router-dom 2.配置 &#xff08;1&#xff09;创建router实例对象并且配置路由对应关系 &#xff08;2&#xff09;路由绑定 import {createBrowserRouter,RouterProvider} from react-router-dom//&#xff08;1&#xff09;创建rou…

web复习(二)

编程题 1.编写一个函数&#xff0c;接收一个数组作为参数&#xff0c;返回一个对象&#xff0c;其中包含数组中每个元素及其出现次数。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewpo…

【CANoe示例分析】Basic UDP Multicast(CAPL)

1、工程路径 C:\Users\Public\Documents\Vector\CANoe\Sample Configurations 16.6.2\Ethernet\Simulation\UDPBasicCAPLMulticast 在CANoe软件上也可以打开此工程:File|Sample Configurations|Ethernet - Simulation of Ethernet ECUs|Basic UDP Multicast(CAPL) 2、示例目…

在Linux(ubuntu22.04)搭建rust开发环境

1.安装rust 1.安装curl: sudo apt install curl 2.安装rust最新版 curl --proto ‘https’ --tlsv1.2 https://sh.rustup.rs -sSf | sh 安装完成后出现&#xff1a;Rust is installed now. Great! 重启当前shell即可 3.检验是否安装成功 rustc --version 结果出现&…

react跳转传参的方法

传参 首先下载命令行 npm react-router-dom 然后引入此代码 前面跳转的是页面 后面传的是你需要传的参数接参 引入此方法 useLocation()&#xff1a;这是 react-router-dom 提供的一个钩子&#xff0c;用于获取当前路由的位置对象location.state&#xff1a;这是从其他页面传…

路径规划之启发式算法之九:灰狼优化算法(Grey Wolf Optimizer,GWO)

灰狼优化算法&#xff08;Grey Wolf Optimizer&#xff0c;GWO&#xff09;是一种智能优化算法&#xff0c;由澳大利亚格里菲斯大学学者Mirjalili等人在2014年提出。该算法灵感来源于灰狼群体的捕食行为&#xff0c;通过模拟灰狼的社会等级分层和狩猎机制来解决复杂的优化问题。…

数字乡村建设方案-6

1. 方案背景与目标 数字乡村建设旨在响应乡村振兴战略&#xff0c;解决顶层设计缺失、资源统筹不足、基础设施缺失等问题&#xff0c;通过信息化建设加强党的领导&#xff0c;提升乡村治理水平&#xff0c;促进乡村经济发展。 2. 乡村信息化需求 乡村管理人员希望通过信息化…

数据分析: 基于CSDN博客排行榜TOP100的博客创作分析和建议

在CSDN上写一些学习心得&#xff0c;分享一些经验&#xff0c;是一件令人愉悦的事情。但是绝大多数人&#xff0c;很多时候写的东西没人看&#xff0c;浏览量个位数&#xff0c;点赞收藏都是0&#xff0c;这着实让人觉得沮丧和无聊&#xff0c;最终选择放弃。 今天&#xff0c…

快速幂+逆元求组合数

在计算组合数 时&#xff0c;直接暴力计算既慢又容易溢出。今天我们来揭开 快速幂 和 模逆元 的神秘面纱&#xff0c;带你一边学习理论&#xff0c;一边轻松解决实际问题&#xff01; 什么是快速幂&#xff1f; 快速幂是一种高效计算 的方法。它利用指数的二进制表示&#x…

「OC」多线程(三)——NSOperation

「OC」多线程(三)——NSOperation 文章目录 「OC」多线程(三)——NSOperation前言介绍实现的具体步骤 NSOperation的创建NSOperationQueue的使用使用实例NSInvocationOperation的使用NSBlockOperation的使用NSOperationQueue的使用取消操作最大并发数 自定义NSOperation子类相关…

可供参考的GitHub国内镜像

在配置了本地hosts文件和魔法后仍存在无法访问的问题 针对如上问题&#xff0c;可以使用国内的镜像地址做替换 例如: https://github.com/bubbliiiing/detr-pytorch改成 https://hub.nuaa.cf/bubbliiiing/detr-pytorch推荐使用的镜像 https://hub.yzuu.cf/ https://hub.nua…

Codeforces Round 784 (Div. 4)

题目链接 A. Division? 题意 思路 模拟即可 示例代码 void solve() {int n;cin >> n;int ans;if(n > 1900) ans 1;else if(n > 1600) ans 2;else if(n > 1400) ans 3;else ans 4;cout << "Division " << ans << \n;}B. T…

E172 ASP.NET+SQL+C#+LW+图书管理系统的设计与实现 配置 源码 文档 全套资料

图书管理系统 1.项目摘要2. 系统的概述3.项目功能4.界面展示5.源码获取 1.项目摘要 摘 要 书籍是供人们获取并增长知识的主要途径&#xff0c;由于图书的种类较多&#xff0c;阅读者也较多&#xff0c;借阅量较大&#xff0c;且易出错&#xff0c;传统的图书借阅若还停留在手工…

TriCore架构-TC397将code从原来在P-Cache地址移到PSPR的地址,CPU的负载率为什么没影响

TC397有6个内核,每个核有自己的私有的Memory以及共有的Memory。 私有的:PSPR,DSPR,P-Cache,D-Cache,PF(X),LMU,DLMU,LPB PSPR主要用来运行RAM Code,比如说有些代码要放到RAM里面运行。 DSPR主要当成SRAM来用,比如用来存放全局变量。 P-Cache通过PFI接口访问DMU的3M内…

109.【C语言】数据结构之二叉树层序遍历

目录 1.知识回顾 2.代码实现 准备工作 LevelOrder函数 代码框架 关键代码 3.执行结果 1.知识回顾 层序遍历参见106.【C语言】数据结构之二叉树的三种递归遍历方式文章 截取的部分内容 定义:按层的方式遍历(,设n为树的深度,h1-->h2-->h3-->...-->hn) 以下面…

基于SpringBoot的养老院管理系统的设计与实现

一、前言 随着人口老龄化的加剧&#xff0c;养老院作为老年人养老的重要场所&#xff0c;其管理的高效性和科学性显得尤为重要。传统的养老院管理方式多依赖人工操作&#xff0c;存在信息记录不及时、不准确&#xff0c;管理流程繁琐&#xff0c;资源调配困难等问题。利用信息技…

012 路由信息协议RIP

路由信息协议RIP 作为度量(Metric)来衡量到达目的网络的距离 RIP是一种基于距离矢量D-V(Distance-Vector)算法的协议&#xff0c;它使用跳数(Hop Count)作为度量(Metric)来衡量到达目的网络的距离。 默认情况下&#xff0c;路由器到与它直接相连网络的跳数为0&#xff0c;因此…

NLP与LLM的工程化实践与学习思考 - 说说知识图谱

NLP与LLM的工程化实践与学习思考[24年半年工作总结] - 说说知识图谱 0 真的就是先说说1 为什么知识图谱什么是知识图谱&#xff1f;基于图的数据结构&#xff1f;基于数据结构的图&#xff1f;知识图谱的技术要点两个技术维度&#xff1a;知识、图七个技术要点&#xff1a;表示…