2.0 Vue框架设计的核心要素

news2024/11/20 3:18:51

本章主要讲解,一个好的框架在构建的时候,需要考虑到的要素,包含报错信息反馈、警告信息反馈、减少打包体积、良好的输出、特性开关(兼容)等

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

函数产生副作用其实是相对于纯函数来说的,纯函数的定义需同时满足以下两条:

  1. 函数在输入相同的情况下总可以得到相同的输出,即该函数的运行并不会依赖于任何外部的数据。
  2. 函数在运行过程中并不会导致外部数据变化,即不会产生副作用。

其实上述函数产生副作用的就是对是不是纯函数的判定,只要满足以上两个条件即为纯函数。在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)
})

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

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

相关文章

3DES实验 思考与练习:

T1&#xff1a;关于3DES的分析 和 库函数的思考——完全领悟了&#xff01;&#xff01;&#xff01; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/des.h> /***********************************************…

java小记

public class Test {/*** 谓类的方法就是指类中用static 修饰的方法&#xff08;非static 为实例方法&#xff09;&#xff0c;比如main 方法&#xff0c;那么可以以main* 方法为例&#xff0c;可直接调用其他类方法&#xff0c;必须通过实例调用实例方法&#xff0c;this 关键…

原生OpenFeign相较于传统HTTP工具的优化和原理

文章目录 1.HTTP工具使用流程及问题1.1 使用OkHttp3流程示例1.2 存在的两大问题 2.OpenFeign的优化3.OpenFeign实现原理3.1 使用Feign构造动态代理对象3.2 Feign动态代理的实现原理 本篇介绍的是springcloud-openfeign的底层框架io.github.openfeign&#xff0c;重点不是框架如…

【Redis】Redis缓存雪崩、缓存穿透、缓存击穿(热key问题)

目录 一、缓存穿透 1、概念 2、解决办法 1.缓存空对象 2.布隆过滤 二、缓存雪崩 1、概念 2、解决办法 1.给key设置随机的过期时间TTL 2.业务添加多级缓存 3.利用集群提供服务可用性 4.缓存业务添加降级限流 三、缓存击穿 1、概念 2、解决办法 1.互斥锁 2.逻辑…

数据结构:第三章 栈、队列和数组

文章目录 一、栈1.1栈的概念1.1.1栈的定义1.1.2栈的基本操作1.1.3栈的常见考题1.1.4小结 1.2栈的顺序存储实现1.2.1顺序栈的定义1.2.2初始化操作1.2.3进栈操作1.2.4出栈操作1.2.5获取栈顶元素操作1.2.6共享栈1.2.7小结 1.3栈的链式存储实现1.3.1链栈的定义1.3.2小结 二、队列2.…

Optional的使用详解

工作中经常会调外部接口、或者查询表等&#xff0c;如果对返回结果不进行空指针判断的话就会导致空指针异常。针对这种情况经常会使用if进行判断: private boolean isNotNull(Object param) {if (param null) {return false;} else {return true;}}这样写其实功能上没有任何问…

上班摸鱼在群里吹牛B,逮到一个阿里10年老测试开发,聊过之后收益良多...

老话说的好&#xff0c;这人呐&#xff0c;一单在某个领域鲜有敌手了&#xff0c;就会闲得蛋疼。前几天我在上班摸鱼刷群的时候认识了一位阿里测试开发大佬&#xff0c;在华为工作了10年&#xff0c;因为本人天赋比较高&#xff0c;平时工作也兢兢业业&#xff0c;现在企业内有…

USB协议分析仪

1 ULPI PHY passive sniffing mode 概念: non driving, no pull-up, no pull-down Function Control.opMode 1; // non-Driving OTG Control.DpPulldown 0; // no pull-down OTG Control.DmPulldown 0; // no pull-down USB IO.ChargerPullupEnDP 0; // no pull-up USB IO.…

九、MyBatis动态SQL

文章目录 九、动态SQL9.1 if9.2 where9.3 trim9.4 choose、when、otherwise9.5 foreach9.6 SQL片段 本人其他相关文章链接 九、动态SQL 9.1 if 总结&#xff1a;根据标签中test属性所对应的表达式决定标签中的内容是否需要拼接到SQL中。 User getUserByParamsWithIf(User user…

缓存击穿,穿透,雪崩

一、缓存穿透 是用户访问的数据既不在缓存当中&#xff0c;也不在数据库中。 如果从数据库查询不到数据&#xff0c;则不写入缓存。这就导致每次请求都会到数据库进行查询&#xff0c;缓存也失去了意义。 当高并发或有人利用不存在的Key频繁攻击时&#xff0c;数据库的压力骤…

AI 工具合辑盘点(四)持续更新

AI 视频生成和编辑工具 当今&#xff0c;视频已经成为最受欢迎的媒介之一。我们喜欢观看视频&#xff0c;但是制作高质量的视频需要耗费大量时间和精力。 无论你是内容创作者、专业视频编辑师&#xff0c;还是完全的新手&#xff0c;按照传统方式制作视频需要掌握各种知识、技…

【Maxwell】MySQL数据监听

背景 我们都知道随着业务的发展,监听数据库的数据变更及时性是必须的,虽然我们可以在入库之前进行处理,但是有个问题就是事务的一致性不好掌控,而且很多业务都是微服务的,那么不在一个微服务中,可能有需要跨服务去调用,那么此时直接去监听mysql的binlog来实现数据的操作…

这一篇Databinding应该可以帮助迅速上手吧

Databinding使用篇&#xff08;迅速上手&#xff09; 使用前需要在模块级别的build.gradle里面的android闭包里添加&#xff1a; dataBinding{enabled true}接着在layout文件中按下Alt 回车&#xff0c; 将布局转换成data binding layout即可&#xff0c;此时编译就会生成对…

【JAVAEE】创建线程的方式及线程的常用方法

目录 1.创建线程的四种方式 1.1继承Thread类 1.2实现Runnable接口 1.3匿名内部类 1.4lambda表达式 2.多线程的优势-增加运行速度 3.Thread类及常用方法 3.1构造方法 3.2常见属性 演示后台线程 演示线程是否存活 3.3线程中断 3.4线程等待-join() 3.5获取当前线程 …

23年5月高项备考学习笔记——信息系统管理

管理&#xff1a;监督系统的设计和结构 系统&#xff1a;提供蓝图 系统管理&#xff1a; 规划和组织&#xff1a;业务战略、组织机制、信息系统 业务战略&#xff1a; 总成本领先战略 差异性战略 专注化战略 设计和实施&#xff1a;战略转成需求&#xff0c;便管理&#xff1b…

5月5号软件资讯更新合集.....

Visual Studio Code 1.78 发布 VS Code 1.78 已发布&#xff0c;此版本一些主要亮点包括&#xff1a; 辅助功能改进 - 更好的屏幕阅读器支持、新的音频提示。 新的颜色主题 - “Modern” 浅色和深色主题默认设置。 配置文件模板 - Python、Java、数据科学等的内置模板。 新…

2023年6月DAMA-CDGA/CDGP数据治理认证报名请尽早啦!

6月18日DAMA-CDGA/CDGP数据治理认证考试开放报名中&#xff01; 考试开放地区&#xff1a;北京、上海、广州、深圳、长沙、呼和浩特、杭州、南京、济南、成都、西安。其他地区凑人数中… DAMA-CDGA/CDGP数据治理认证开班时间&#xff1a;5月7日 DAMA认证为数据管理专业人士提供…

线上FullGC问题排查实践——手把手教你排查线上问题 | 京东云技术团队

作者&#xff1a;京东科技 韩国凯 一、问题发现与排查 1.1 找到问题原因 问题起因是我们收到了jdos的容器CPU告警&#xff0c;CPU使用率已经达到104% 观察该机器日志发现&#xff0c;此时有很多线程在执行跑批任务。正常来说&#xff0c;跑批任务是低CPU高内存型&#xff0c…

【马蹄集】第九周作业

第九周作业 目录 MT2125 一样的虫子MT2126 AB数对MT2127 权值计算MT2128 黑客小码哥MT2129 来给单词分类 MT2125 一样的虫子 难度&#xff1a;黄金    时间限制&#xff1a;1秒    占用内存&#xff1a;128M 题目描述 有 N 只虫子&#xff0c;每只虫子有6条腿&#xff0c;每…

通过Python的pytesseract库识别图片中的文字

文章目录 前言一、pytesseract1.pytesseract是什么&#xff1f;2.安装pytesseract3.查看pytesseract版本4.安装PIL5.查看PIL版本 二、Tesseract OCR1.Tesseract OCR是什么&#xff1f;2.安装Tesseract OCR3.安装 Tesseract OCR 语言包 三、使用方法1.引入库2.打开图片文件3.使用…