Vue.js设计与实现阅读-2

Vue.js设计与实现阅读-2

    • 1、前言
    • 2、框架设计的核心要素
        • 2、1 提升用户体验
        • 2、2 控制代码体积
        • 2、3 Tree-Shaking
        • 2、4 特性开关
        • 2、5 错误处理

1、前言

上一篇我们了解到了

  • 命令式和声明式的区别,前者关注过程,后者关注结果
  • 了解了虚拟dom存在的意义,使找出差异这个过程消耗的性能最小化
  • 学习了进行时、编译时、编译时+进行时的特点,初步知道了vue3是采用编译时+进行时的框架

2、框架设计的核心要素

2、1 提升用户体验
好的用户开发体验,是衡量框架是否优秀的指标之一。

提供友好的警告信息

在这里插入图片描述
当我们创建一个Vue.js应用,并把他挂载在一个不存在的dom节点,就会发现控制台有 warning 信息。
在这里插入图片描述
从警告信息中,能够快速知道失败原因,我们提供的选择器没有找到对应的 DOM 元素。如果Vue 内部不做处理,可能得到的是 Uncaught TypeError: Cannot read property ‘xxx’ of null 就不能很快定位到问题。

那 Vue 中是如何实现的,可以看 Vue 源码中有 warn 函数的调用

看代码可以看到,在创建Vue应用的时候,app.mount中调用了一个 normalizeContainer 函数,对于传入的参数进行处理,确保是一个有效的 DOM 元素。
在这里插入图片描述
在 normalizeContainer 函数中,可以看到图中圈出的 if 判断,当 处于开发者模式并且 通过 document.querySelector 方法没有找到匹配的 DOM 元素时,会输出警告信息。
在这里插入图片描述

再往里面看 warn 函数,发现最终都是调用了 console.warn 函数,进行输出警告在这里插入图片描述

2、2 控制代码体积
框架的大小也是衡量框架的标准。同样情况下,使用的代码越少,体积就越小,浏览器加载资源的时间越少。
但是 Vue 中有大量的提示信息,越完善的提示信息就意味着越多的代码。
那 Vue3 中是如何处理的

看代码 会发现 每一个调用 warn 函数的地方 都会配合 __DEV __ 的常量检查
在这里插入图片描述
只有当 __DEV __ 为 true 的 前提下,才有可能会打印警告信息。这里的 DEV 常量就是达到目的的关键。

Vue.js 在输出资源的时候,会输出两个版本,开发环境和生产环境。当 Vue.js 构建用于开发环境的时候,会把 __DEV __ 设置为 true ,当处于生产环境的时候会设置为 false。那么那段警告代码就永远不会执行。
就能实现在开发环境为用户提供友好的警告信息,在生产环境中却不会增加代码体积。

2、3 Tree-Shaking

上面说到通过设置预定义常量 __DEV __ ,能够在生产环境中不包含用于打印警告信息的代码。但是这还不够,比如Vue内有很多组件,比如< transition > 组件,我们可能项目中都没用到这个组件,那他应该不需要包含在我们项目最终的构建资源中。Vue是如何实现的呢?

先揭晓答案吧,是通过 Tree-Shaking 实现的。 Tree-Shaking 用来消除那些永远不会被执行的代码(排除 dead code)。rollup.js和webpack 都支持 Tree-Shaking 。来看下 webpack 中, Tree-Shaking 如何工作。参考文档Tree-Shaking

创建一个 webpack 项目, 目录结构如下:
在这里插入图片描述
配置 webpack.config.js 如下

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  mode: 'development',
  optimization: {
   usedExports: true,
 },
};

其中在 math 中导出了两个方法:

export function square(x) {
    return x * x;
}

export function cube(x) {
    return x * x * x;
}

index.js 中调用 了 cube 方法

import { cube } from './math.js';

function component() {
    const element = document.createElement('pre');
    element.innerHTML = [
        '你好 webpack!',
        '5 的立方等于 ' + cube(5)
      ].join('\n\n');

    return element;
}

document.body.appendChild(component());

注意这里我们并没有导出 square 函数,按理说,最终的编译打包产物中应该是没有 square 函数的相关内容的。我们继续往下查看结果

使用 npm run build 查看 bundle.js中打包编译后的结果。
在这里插入图片描述

/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */  cube: () => (/* binding */ cube)\n/* harmony export */ });\n/* unused harmony export square */\nfunction square(x) {\n    return x * x;\n  }\n  \n  function cube(x) {\n    return x * x * x;\n  }\n\n//# sourceURL=webpack://webpack-demo/./src/math.js?");

/***/ })

/******/ 	});

看上方的 unused harmony export square 注释。仔细观察下面的代码会发现尽管没有引用 square,但它仍然被包含在 bundle 中。
在纯 ES 模块中,很容易识别出哪些文件有副作用,但是我们的项目没有办法达到这种纯度,因此我们需要提示 webpack 编译器哪些代码是纯粹的。

我们可以通过 /#PURE/ 注释来帮助 webpack,告诉他某个函数调用无副作用,她会被标记为 dead code,不会被执行且会被清除掉。
我们尝试在 square 函数前面加上这样一个标记,然后再来看 bundle.js 中的输出,可以看到已经没有 square函数的引入了。

(()=>{"use strict";document.body.appendChild(function(){const n=document.createElement("pre");return n.innerHTML=["你好 webpack!","5 的立方等于 "+(5,125)].join("\n\n"),n}())})();

基于以上 我们可以看到,在编写框架的时候可以合理的使用 /#PURE/ 注释。查看 Vue3 的源码,可以发现大量的 /#PURE/ 使用。
在这里插入图片描述

2、4 特性开关

设计框架的时候,会给用户提供多种功能,例如提供 A、B、C三个特性给用户,同时提供了a、b、c三个对应的开关,用户可以通过设置 a、b、c 为true 或者 false,代表开启或者关闭特性。
对于设置关闭的特性,可以利用 Tree-Shaking 机制让其不包含在最终资源中,带来了极大灵活性。

如何实现特性开关。其实类似于上面的 DEV 常量一样,本质上是利用 rollup.js 来预定义常量插件来实现。
比如 VUE_OPTIONS_API

      __FEATURE_OPTIONS_API__: isBundlerESMBuild
        ? `__VUE_OPTIONS_API__`
        : `true`,

其中 VUE_OPTIONS_API 是一个特性开关,用户可以通过设置 VUE_OPTIONS_API 预定义常量的值来控制是否要包含这段代码,这个标志是用来对 Vue2 做适配.
比如 Vue2中的 template、data 等选项其实都属于 Options API,但在 Vue3 中,这种 Options API 写得相对来说就比较少了,
现在一般在 Vue3 中编写 Composition API,默认情况下,这个 VUE_OPTIONS_API 标志默认值是 true,这就意味着默认情况下 Vue3 项目中会包含支持 Options API 的这部分代码。
那么,如果在项目中编写的都是 Composition API 代码,其实就不再需要这部分解析 Options API 的代码了,那么可以通过 设置 VUE_OPTIONS_API 为true,来剔除掉一些无用大代码,减少代码体积。

2、5 错误处理

错误处理是框架开发的重要环节。
假设我们提供了一个方法,

export default {
	foo(fn) {
		fn && fn()
	}
}

用户侧使用

import utils from 'utils.js'
utils.foo(() => {
	...
})

如果函数执行出错,有两个方法,1用户自己执行 try…catch处理

import utils from 'utils.js'
utils.foo(() => {
	try {
		//...
	} catch(e) {
		//...
	}
})

这样的话,用户每使用一个函数,都需要加一个错误处理程序。很烦。
第二个就是我们内部统一处理,封装一个错误处理函数, callWithErrorHandling。

export default {
	foo(fn) {
		callWithErrorHandling(fn)
	},
	bar(fn) {
		callWithErrorHandling(fn)
	}
}
function callWithErrorHandling(fn) {
	try {
		fn && fn()
	} catch(e) {
		console.log(e)
	}
}

这样代码看起来简洁,再升级下可以为用户提供统一的错误处理接口。

let handleError = null
export default {
	foo(fn) {
		callWithErrorHandling(fn)
	},
	// 暴露给用户,用户可以调用该函数注册统一的处理函数
	registerErrorHandler(fn) {
		handleError = fn
	}
}
function callWithErrorHandling(fn) {
	try {
		fn && fn()
	} catch(e) {
	// 将错误传递给用户的错误处理程序
		handleError(e)
	}
}

用户侧

import utils from 'utils.js'  // 注册错误处理程序
utils.registerErrorHandler((e) => {
	// 做统一的处理,可以选择忽略,可以上报。
   console.log(e)
 })
 utils.foo(() => {/*...*/})
 utils.bar(() => {/*...*/})

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库SELECT语句

文章目录 一、检索数据二、排序检索三、过滤数据四、数据过滤4.1 组合WHERE子句1. AND操作符2. OR操作符3. 计算次序 4.2 IN操作符4.3 NOT操作符 五、用通配符过滤LIKE操作符1. 百分号&#xff08;%&#xff09;通配符2. 下划线&#xff08;_&#xff09;通配符 使用通配符的技…

盈利之道:下单前的必问之问

投资者在过去的交易经历中&#xff0c;通常都会面临所谓的“交易低谷”。交易低谷是指在交易过程中难以实现盈利或可能导致进一步亏损的阶段。这种面临损失或没有盈利的时期可能发生在任何人身上&#xff0c;无论是由于市场变化、投资者策略调整还是其他原因。为了应对这种情况…

CSS基础方法——引入方式、属性、基础选择器

CSS 主要用于设置 HTML 页面中的文本样式&#xff08;字体、大小、颜色、对齐方式……&#xff09;、图片样式&#xff08;宽高、边框样式、边距……&#xff09;以及版面的布局和外观显示样式。 1、CSS引入方式 行内样式 写在标签中&#xff0c;通常不使用&#xff0c;只做…

优惠券兑换码生成需求——事务同步回调问题分析

前段时间收到一个优惠券兑换码的需求&#xff1a;管理后台针对一个优惠券发起批量生成兑换码&#xff0c;这些兑换码可以导出分发到各个合作渠道&#xff08;比如&#xff1a;抖音、京东等&#xff09;&#xff0c;用户通过这些渠道获取到兑换码之后&#xff0c;再登录到我司研…

提升测试效率,轻松并行运行测试——探秘Pytest插件pytest-xdist

在软件开发中&#xff0c;测试是确保代码质量的重要一环。然而&#xff0c;随着项目规模的增大&#xff0c;测试用例的数量也随之增多&#xff0c;测试的执行时间可能成为一个瓶颈。为了解决这个问题&#xff0c;Pytest提供了丰富的插件生态系统&#xff0c;其中 pytest-xdist …

黑群晖6.x 7.x ABB Active Backup for Business 套件激活方法

注意事项&#xff1a; 要先下载安装好Active Backup for Business套件再操作。SN码在【控制面板】 - 【信息中心】 -【产品序列号】。建议复制到记事本内修改内容。群晖的https是默认的5001端口&#xff0c;如果你的https端口号换过请自行修改&#xff1a;5001 为当前的端口号…

spacedesk 变成黑白的分析

测试发现只要调整时间到2024 就会出现黑白而且是建立连接是才检测的&#xff0c;那么应该存在于R3部分的可能性大 IDA分析找到2024

[论文阅读]4DRadarSLAM: A 4D Imaging Radar SLAM System for Large-scale Environments

目录 1.摘要和引言&#xff1a; 2. 系统框架&#xff1a; 2.1 前端&#xff1a; 2.2 回环检测&#xff1a; 2.3 后端&#xff1a; 3.实验和分析&#xff1a; 4.结论 1.摘要和引言&#xff1a; 这篇论文介绍了一种名为“4DRadarSLAM”的新型4D成像雷达SLAM系统&#xff0…

RT-DETR优化:UNetv2多层次特征融合模块结合DualConv、GSConv

🚀🚀🚀本文改进:多层次特征融合(SDI)结合DualConv、GSConv模块等实现二次创新 🚀🚀🚀SDI 亲测在多个数据集能够实现涨点,同样适用于小目标检测 🚀🚀🚀RT-DETR改进创新专栏:http://t.csdnimg.cn/vuQTz 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定…

Vue、uniApp、微信小程序、Html5等实现数缓存

此文章带你实现前端缓存&#xff0c;利用时间戳封装一个类似于Redis可以添加过期时间的缓存工具 不仅可以实现对缓存数据设置过期时间&#xff0c;还可以自定义是否需要对缓存数据进行加密处理 工具介绍说明 对缓存数据进行非对称加密处理 对必要数据进行缓存&#xff0c;并…

太平洋产险海南分公司:春季爱车保养,就看这几点!

一年之计在于春&#xff0c;春天不仅是万物复苏的好时节&#xff0c;也是一年中非常适合汽车养护的季节。 刚刚过去的春节&#xff0c;汽车的使用频率大大增加&#xff0c;很多车主都准备对爱车进行一次全面保养。加上立春过后&#xff0c;天气渐暖&#xff0c;许多车主也计划开…

答题小程序源码系统:自带流量主广告位+视频激励广告 带完整的代码安装包以及搭建教程

随着互联网的迅速发展&#xff0c;各种应用程序层出不穷&#xff0c;而答题类小程序由于其独特的互动性和吸引力&#xff0c;成为了当前最热门的应用之一。答题小程序源码系统是一款基于微信小程序开发的源代码系统&#xff0c;它具有丰富的功能和灵活的定制性&#xff0c;可以…

搭建算法日志自检小系统

&#x1f952; 前言 目前演示的是一个工具&#xff0c;但如此&#xff0c;未来完成有潜力可以演变为一整套系统。 &#x1f451;现场人员自检失败表计点位教程V2.0 NOTE: 如果没有“logfiles-meter-tool“目录的请联系我们进行提供&#xff01; &#x1f447; 进入<dist>…

使用AutoDL云计算平台训练并测试Pytorch版本NeRF代码

文章目录 前言一、数据集及代码获取二、租用并设置服务器三、Pycharm远程开发四、训练并测试代码 前言 因为第一次在云服务器上跑代码&#xff0c;所以在这里记录一下。 一、数据集及代码获取 nerf-pytorch项目是 NeRF 的忠实 PyTorch 实现&#xff0c;它在运行速度提高 1.3 倍…

docker 利用特权模式逃逸并拿下主机

docker 利用特权模式逃逸并拿下主机 在溯源反制过程中&#xff0c;会经常遇到一些有趣的玩法&#xff0c;这里给大家分享一种docker在特权模式下逃逸&#xff0c;并拿下主机权限的玩法。 前言 在一次溯源反制过程中&#xff0c;发现了一个主机&#xff0c;经过资产收集之后&…

SSL证书与HTTPS的关系

SSL证书是一种数字证书&#xff0c;由权威的证书颁发机构颁发。它包含了一个公钥和有关证书所有者的一些信息&#xff0c;如名称、组织、邮箱等。SSL证书的主要作用是实现数据加密和身份验证&#xff0c;确保数据在传输过程中的安全性和完整性。 HTTPS是一种基于HTTP协议的安全…

Web开发:SQLsugar的安装和使用

一、安装 第一步&#xff0c;在你的项目中找到解决方案&#xff0c;右键-管理解决方案的Nuget 第二步&#xff0c;下载对应的包&#xff0c;注意你的框架是哪个就下载哪个的包&#xff0c;一个项目安装一次包即可 点击应用和确定 安装好后会显示sqlsugar的包 二、使用&#xf…

UOS Python+Qt5实现声卡回路测试

1.回路治具设计&#xff1a; 2.Ui界面&#xff1a; 3.源代码&#xff1a; # -*- coding: utf-8 -*-# Form implementation generated from reading ui file SoundTestWinFrm.ui # # Created by: PyQt5 UI code generator 5.15.2 # # WARNING: Any manual changes made to this…

3d云渲染用什么显卡比较好?3d云渲染显卡推荐

3D云渲染能加快渲染速度&#xff0c;是众多公司的首选方案&#xff0c;作为公司负责人&#xff0c;选择哪个平台值得思考&#xff0c;今天我就说下我的选择吧。 首先我们要了解云渲染的渲染方式&#xff0c;云渲染的渲染方式分两种&#xff0c;一种是CPU渲染&#xff0c;一种是…