2.0 Vue框架设计的核心要素
本章主要讲解,一个好的框架在构建的时候,需要考虑到的要素,包含报错信息反馈、警告信息反馈、减少打包体积、良好的输出、特性开关(兼容)等
1、提升用户开发体验
提升用户开发体验主要体现在用户使用框架进行开发时,框架能够提供良好的交互体验,如及时的警告。这在Vue.js中做的很好,在源码中可以看到各个部分都有很多的warn函数的调用,并且在warn函数中尽可能提供了有用信息。
并且Vue.js支持使用自定义的打印数据,比如当打印reacitve或者ref时打印出的信息并不直观。打印const value = ref(0)
中value的值时,打印结果为:
为了解决这一问题,Vue.js可以通过DevTools更改其Console选项设定合适的输出结果。
2、控制框架代码的体积
在保证功能完善的情况下肯定是使用的代码越少越好,但是根据上述情况为了提升开发者体验加入了很多警告信息,这些信息会让代码体积增多。
其实做过项目开发者都知道,在项目中分为开发者模式和生产模式。根据不同的模式削减代码以控制代码体积,比如警告信息只会出现在开发者模式之下。所以在Vue.js的源码中所有的warn信息都加入了控制的字段。
if(__DEV__ && !res) {warn(// 警告信息)
}
这里的__DEV__
只有在开发模式之下会被替换成字面量true
,所以在非开发模式下上面的警告部分的代码就会变成dead code,在最后打包输出的时候被移除。
这样就做到了友好的开发,并且在生成环境下不会产生冗余代码。
3、框架做到良好的Tree-Shaking
Tree-Shaking就是将项目中永远不会执行的代码打包时删去,如上所说的警告信息在生产环境下属于dead code在打包的时候需要被去除,那么怎么区分代码是否会被执行呢。
要使用Tree-Shaking那么模块必须是ESM(ES Module),因为Tree-Shaking依赖ESM的静态结构。对于ESM来说模块是静态引入的,可以不依靠运行程序进行分析,即所谓的静态分析。
在打包时根据入口文件无法到达的代码会被舍弃。同时如果一个函数有副作用那么这个函数也是不会被删去的,比如:
const data = {value: 1} let getCount = 0
// 副作用函数,计数value被获取的次数,修改全局遍历getCount
function countAdd(target, key) {getCount += 1
}
// 对data对象进行代理
const obj = new Proxy(data, {get(target, key) {// 在获取value的时候执行副作用函数countAdd(target, key)return target[key]}
})console.log(obj.value)
此时函数countAdd
在执行时会改变变量getCount
的值,即这个函数产生了副作用,所以这个函数是不属于dead code。
函数产生副作用其实是相对于纯函数来说的,纯函数的定义需同时满足以下两条:
- 函数在输入相同的情况下总可以得到相同的输出,即该函数的运行并不会依赖于任何外部的数据。
- 函数在运行过程中并不会导致外部数据变化,即不会产生副作用。
其实上述函数产生副作用的就是对是不是纯函数的判定,只要满足以上两个条件即为纯函数。在Vue框架内可以在函数的前面加注释/*# __PURE__*/
来对其进行Tree-Shaking。这在Vue.js3源码中可以看到很多这样的函数注释。
4、特性开关
在Vue的框架设计中会设计很多的特性(功能),同时在框架迭代的过程中也会产生很多的遗留API,这些功能在一个项目中可能不会完全用到,或者随着框架越来越臃肿打包体积会越来越大。所以一个良好的框架肯定会对相应的功能设置特性开关,将不需要的功能关掉,在打包的时候忽略掉,减少打包的体积。
特性开关的功能实现也和上文提到的__DEV__
常量一样,给这些功能设定一个一个的常量,通过给常量赋值来决定功能是否开启。
比如在Vue2中我们使用的是选项型API,其data、methods、computed…是区分开来的:
export default {data() {}, //data选项computed() {}, //computed选项// 其他选项
}
而在Vue3中使用的是组合型API,其代码结构可以根据功能划分,如:
export default {setup() {const count = ref(1)const doubleCount = computed(() => count.value * 2)// 其他功能代码}
}
在Vue3中其实我们也是可以使用选项型API的,根据__VUE_OPTIONS_API__
开关来开闭该特性,这是理解特性开关一个很好的例子。
其实Vue3选择使用组合型API的好处很多,大家最常说的是后期维护和大页面编写更加的友善了,因为之前的选项型API需要把数据放一部分,函数放一部分…根据类型来做区分,在后面需要对相应功能修改的时候需要滑上滑下地寻找,而选项型API可以把相应的功能代码放在一块,代码定位更加简单。
其实组合型API的改变更多的是一种思维上的变化,从关注数据到关注功能,这样以功能为核心可以更加的灵活,对于相同功能的代码复用,嵌套等更加轻松灵活。
5、报错处理
无论在什么框架中报错处理都是一个十分重要的环节,框架错误处理机制决定了用户程序的健壮性,同时好的报错处理机制也减少了开发者的心智负担。
假设我们有一个函数,接收一个回调函数,然后执行该回调函数,简单可以这样写:
function foo(fn) {fn && fn()
}
此时如果用户提供的回调函数出错怎么办?其实可以使用try…catch捕获
function foo(fn) {try {fn && fn()} catch(e) {console.log(e)}
}
但是有个问题,比如我们现在有很多个工具函数,都是接受回调函数,然后执行,那么全部使用try…catch是十分臃肿的,那么进一步可以封装出一个报错的函数。
// 统一报错函数
function callWithEroorHandling(fn) {try {fn && fn()} catch(e) {console.log(e)}
}
//这里直接调用
function foo(fn) {callWithEroorHandling(fn)
}
function bar(fn) {callWithEroorHandling(fn)
}
将报错处理部分单独提出来,统一处理:
let handleError = null
function registerErrorHandle(fn) {handleError = fn
}
function callWithEroorHandling(fn) {// 执行程序try {fn && fn()} catch(e) {// 报错后给注册的报错处理函数handleError(e)}
}
// 注册报错之后的处理
registerErrorHandle((e) => {console.log("注册报错!")console.log(e)
})
相关文章:

2.0 Vue框架设计的核心要素
本章主要讲解,一个好的框架在构建的时候,需要考虑到的要素,包含报错信息反馈、警告信息反馈、减少打包体积、良好的输出、特性开关(兼容)等 1、提升用户开发体验 提升用户开发体验主要体现在用户使用框架进行开发时&…...

“智慧赋能 强链塑链”——精细化工行业仓储物流数字化转型探讨
精细化工行业作为衡量国家化学工业水平高低的重要标志,为国民经济提供重要的终端产品支持,相比较大化工产品,精细化工产品需要高度专业技能和工艺,其生产过程需要复杂的化学反应,以及严格的控制条件,产出的…...

用DG备库做的rman备份恢复一个数据库
环境描述: 1.因为主库存储空间不足,于是将备份放在dg备库上做。 2.主库因为磁盘空间问题,数据文件有两个目录。 3.dg备库因为主库两个数据文件目录里面有两个同名数据文件,所有dg备库也有两个数据文件目录。 4.主库与备库与测…...
JAVA中的IO操作有哪些?
在Java编程语言中,输入/输出(IO)操作是很重要的部分,它允许程序从外部系统读取数据,或将数据输出到外部系统。Java提供了一组强大的IO类库,可以让开发人员方便地进行各种IO操作。 Java中的IO操作可以分为两…...

10:00面试,10:04就出来了 ,问的实在是太...
从外包出来,没想到竟然死在了另一家厂子 自从加入这家公司,每天都在加班,钱倒是给的不少,所以我也就忍了。没想到12月一纸通知,所有人都不许加班,薪资直降30%,顿时有吃不起饭的赶脚。 好在有个…...

wangzherongyao PMO
感谢【五一节】大家的相遇,总结下。 2023年05月02日,【第一组】组队开黑 我总结了下这天为什么打的那么好,首先赛季初段位在王者附近,大家心态重视程度也高,不轻敌,也不盲目,运营好兵线一步一步…...
Dart语法上
一、Dart介绍及环境 1.1 Dart介绍: Dart是由谷歌开发的计算机编程语言,它可以被用于web、服务器、移动应用 和物联网等领域的开发。Dart诞生于2011年,号称要取代JavaScript。但是过去的几年中一直不温不火。直到Flutter的出现现在被人们重新重视。 要学…...

SignOff Criteria——POCV(Parametric OCV) introduction
文章目录 1. O v e r v i e w Overview Overview2. P O C V A n a l y s i s POCV\ Analysis POCV Analysis3. P O C V F l o w POCV\ Flow POCV Flow4. P O C V R e p o r t POCV\ Report POCV Report 1. O v e r v i e w Overview Overview P r o c e s s v a r i a t i…...

Android 内存分析(java/native heap内存、虚拟内存、处理器内存 )
1.jvm 堆内存(dalvik 堆内存) 不同手机中app进程的 jvm 堆内存是不同的,因厂商在出厂设备时会自定义设置其峰值。比如,在Android Studio 创建模拟器时,会设置jvm heap 默认384m , 如下图所示: 当app 进程中java 层 new 对象(加起来总和)占用…...
产品思维与工程师思维
目录标题 什么是产品思维用户痛点体验价值 产品思维与工程师思维有什么区别?产品需要什么能力洞察需求的能力逻辑思维能力成本意识 场景化思维和用户体验数据分析和售后服务数据分析服务大多数用户原则 什么是产品思维 产品思维就是考虑产品的方方面面,…...
Android---启动速度优化
App 启动流程 1. 点击桌面 App 图标,Launcher 进程采用 Binder IPC 向 system_server 进程发起 startActivity 请求 ; 2. system_server 进程接收到请求后,向 zygote 进程发送创建进程的请求; 3. zygote 进程 fork 出新的子进程…...

使用 Mercury 直接从 Jupyter 构建 Web 程序
动动发财的小手,点个赞吧! 有效的沟通在所有数据驱动的项目中都至关重要。数据专业人员通常需要将他们的发现和见解传达给利益相关者,包括业务领导、技术团队和其他数据科学家。 虽然传达数据见解的传统方法(如 PowerPoint 演示文…...

Python基础(二)
目录 一、类型转换 1、为什么需要数据类型转换 2、数据类型转化的函数 3、str()函数类型转换使用 4、int()函数类型转换使用 4.1int()不能将str类型数据转换成int 4.2int()将bool类型转换成int 4.3int()将float转换成int 5、Float()函数类型转换使用 5.1Float()函数不…...
第41讲:Python循环语句中的break-else语法结构
文章目录 1.在循环正常结束后执行动作的思路2.通过控制布尔值变量的方式在循环正常结束后执行某些操作2.1.while循环语句2.2.for-in循环语句3.通过else从句来执行某些操作1.在循环正常结束后执行动作的思路 在执行while循环语句或者for循环语句时,如果循环是正常结束的,非执…...
双系统-真机安装ubuntu
服务器系统最好选择legacy启动mbr硬盘,数据盘可以使用gpt格式,超过2t的只能用gpt。 华为2288v3用uefi找不到启动硬盘,或者是找到硬盘后无法引导,迁移系统得到有efi引导文件的硬盘也不行,选择用legacy吧。 ubuntu默认uefi启动,若使用legacy,则需要easybcd处理一下引导。 …...
Android实现向facebook回复消息代码
以下是一个示例代码,它基于Facebook SDK版本5.0,具体实现如下: 1. 集成Facebook SDK库 下载Facebook SDK并将其加入到Android Gradle构建文件中,像这样: groovy dependencies { implementation com.facebook.an…...

IDEA小技巧-Git的回滚强推代码找回
标题IDEA小技巧-Git的回滚&&强推&&代码找回 本地未Commit 新增文件 delete 变更文件 rollback 第一种方式 第二种方式 切换默认变更列表 Commit未push undo commit 仅适用于最后一次的提交进行回滚 drop commit 回滚 revert commit revert commi…...
即时通讯为什么不采用UDP的连接方式呢
即时通讯为什么不采用UDP的连接方式呢 博主今天从网络上找了几个比较关注的热点的内容进行讲解 1.首先介绍一下UDP连接的缺点 不可靠:UDP是一种无连接的传输协议,它不提供数据包的可靠传输保证。这意味着当使用UDP进行通信时,数据包可能会丢…...
二叉树(纲领篇)
文档阅读 文档阅读 二叉树解题的思维模式分两类: 1、是否可以通过遍历一遍二叉树得到答案?如果可以,用一个 traverse 函数配合外部变量来实现,这叫「遍历」的思维模式。 2、是否可以定义一个递归函数,通过子问题&a…...
day41—选择题
文章目录 1.某主机的IP 地址为 180.80.77.55,子网掩码为 255.255.252.0。若该主机向其所在子网发送广播分组,则目的地址可以是(D)2.ARP 协议的功能是(A)3.以太网的MAC 协议提供的是(A࿰…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...