作者:京东物流 吴云阔

1 前言

Vue3已经正式发布了一段时间了,各种生态已经成熟。最近使用taro+vue3重构冷链的小程序,经过了一段时间的开发和使用,有了一些自己的思考。

总的来说,Vue3无论是在底层原理还是在实际开发过程中,都有了很大的进步。

从源码层面来说,使用Proxy代替Object.defineProperty的API,一个是代理的对象,一个是递归监控的属性,从而在性能上有了很大的进步,并且,也解决了对象动态属性增加、数组改变监听上的缺陷;对diff算法进行优化,增加了静态标记,大大提高了Vue的执行效率;还有静态提升、事件监听缓存等一系列提升效率的手段。

从应用层面来说,主要的改变是将option API改成了composition API(组合式API),在业务中抛弃data、methods、生命周期函数隔离开的开发方式,使代码相对于业务有更强的聚合性,在代码开发、代码阅读、代码维护方面对于开发者都是更加友好。

对于typescript有了更好的支持,我们知道,对于大型的前端项目来说,使用typescript的类型校验,能使前端项目有更强的健壮性,这也使得Vue3对于大型项目的开发提供了更强的质量保证。

2 组合式API

所谓的组合式API,将Vue2中的data、methods、生命周期、数据监听等option,都封装成钩子函数,然后组合到setup函数中,其核心就在于setup函数。setup函数存在的意义,就是为了使用这些新增的组合式API,并且这些API只能在setup函数中使用。

setup函数执行的时机是,props初始化之后,beforeCreate函数执行之前,所以在执行setup时,还没有初始化Vue实例,因此在setup中不能使用this对象。setup函数的返回值会被注入到Vue实例中,供Vue组件使用,所以任何数据想在Vue组件的模板中使用,必须在setup函数中return出去。

组合式API的组合,体现在两个层面。第一层的意思是,将某一业务相关数据和处理逻辑放到一起,这是一种关注点的聚合,更方便我们编写代码、处理业务逻辑,并且能更聚焦业务逻辑,更方便我们看代码。第二层面的意思,当某个组件的业务逻辑足够复杂,setup中的代码足够大的情况下,我们可以在setup内部,进一步提取相关的一块业务,使代码逻辑更加清晰,做到了进一步的聚合作用。

如下面代码所示,将业务代码块A抽出来,则代码块A中return出来的数据就可以在组件中使用:

  1. // 组件

  2. import functionA from 'A'

  3. export default defineComponent({

  4. name: 'componentName',

  5. setup() {

  6. ...functionA()

  7. }

  8. })

  9. // 代码块A

  10. export default () => {

  11. return {

  12. a: 1

  13. }

  14. }

3 响应式API

在Vue3中响应式API,主要体现在ref和reactive两个函数。对于响应式API,想说两个问题,第一个是为什么要增加响应式API,第二个是响应式API函数ref和reactive的异同点。

3.1 为什么增加响应式API

在Vue2中所有数据都写在data的option中,data中的数据都是响应式的,这样产生的一个问题是,有些常量数据本身不需要监听,从而造成了资源的浪费。所以在Vue3中增加了响应式API,只需要对需要动态更新dom的数据进行响应式,不需要动态更新dom的数据不进行响应式处理,从很大程度上节省了资源。这里我觉得需要注意的是,写代码的时候一定要仔细思考一下,哪些数据需要进行响应式绑定,哪些数据不需要进行响应式绑定,而不是一股脑的全给绑定上,这样即使代码逻辑不能很清晰易懂,并且也会影响执行效率(写惯了Vue2的同学需要注意)。

3.2 ref和reactive的异同点

在了解了为什么要增加响应式API后,我们发现Vue3提供了两个响应式API函数,ref和reactive。为什么会提供两个API呢? 一个不就可以了吗?那么这两个API之间的区别是什么呢?

在使用层面,ref绑定的数据,需要使用[data].value进行数据更改。而reactive绑定的数据需要使用[data].[prpoerty]的方式进行数据更改。在使用场景方面,一般的,单个的普通数据,我们使用ref来定义响应式。而复杂数据,如:表单数据对象、某一模块的一组数据等,使用reactive来定义响应式。

那么,对象是不是必须用reactive来定义呢? 其实不是的,都可以。官方说法是:可以根据自身习惯使用不同的API。其实,我觉得,他们是有各自的使用场景的,ref更强调的是数据Value的改变,reactive更强调的是数据中某一属性的改变。

4 treeShaking思想

当 Javascript 项目达到一定体积时,将代码分成模块会更易于管理。但是,当这样做时,我们最终可能会导入实际上未使用的代码。Tree Shaking 是一种通过消除最终文件中未使用的代码来优化体积的方法。

Vue3使用了tree shaking的方法,将组件以及其所有的生命周期函数等方法进行分开,如果在组件中使用的代码将不会出现在最终的打包文件中,如此,会减少大大Vue3项目的打包体积。由此造成的一个结果就是,使用方法的不同。

4.1 生命周期函数的使用方法

  1. import { defineComponent, ref, onMounted } from 'vue';
  2. export default defineComponent({
  3. name: 'Gift',
  4. setup() {
  5. const counter = ref(0);
  6. onMounted(() => {
  7. // 处理业务,一般进行数据请求
  8. })
  9. return {
  10. counter
  11. }
  12. }
  13. })

4.2 Vuex的使用方法

  1. import { useStore } from "vuex";
  2. import { defineComponent, ref, computed } from 'vue';
  3. export default defineComponent({
  4. name: 'Gift',
  5. setup() {
  6. const counter = ref(0);
  7. const store = useStore();
  8. const storeData = computed(() => store); // 配合computed,获取store的值。
  9. return {
  10. counter,
  11. storeData
  12. }
  13. }
  14. })

4.3 Router的使用方法

  1. import { useStore } from "vuex";
  2. import { useRouter } from "vue-router";
  3. import { defineComponent, ref, computed } from 'vue';
  4. export default defineComponent({
  5. name: 'Gift',
  6. setup() {
  7. const counter = ref(0);
  8. const router = useRouter();
  9. const onClick = () => {
  10. router.push({ name: "AddGift" });
  11. }
  12. return {
  13. counter,
  14. onClick
  15. }
  16. }
  17. })

5 关于Typescript的使用

这一部分是关于Ts的内容,不过它与Vue3的开发息息相关。Vue3整体是使用Ts写的,因此,开发Vue3的项目需要使用Ts,所以,我们还是要了解TS的。

关于Ts的使用这里就不在细说了,在这里想说的的是,在实际业务场景中是如何组织Ts代码的。通过对TS的大量使用,我的一个体会是:Ts的核心思维是先关注数据结构,在根据数据结构进行页面开发。而以前的前端开发模式是,先写页面,然后再关注数据。

比如说,我们要开发一个页面,我们可能需要先定义一些interface。开发页面的时候我们要关注:页面数据的interface、接口返回数据的类型、请求参数的类型等等。

下面是开发一个列表页面的例子:

  1. // 这是列表中每一项的数据类型

  2. interface IDataItem {

  3. id: string | number;

  4. name: string;

  5. desc: string;

  6. [key: string]: any;

  7. }

  8. // 接口返回值类型, 一般来说,我们不确定接口返回的数据的类型,因此使用泛型

  9. interface IRes<T> {

  10. code: number;

  11. msg: string;

  12. data: T

  13. }

  14. // 口返回数据类型定义

  15. interface IDataInfo {

  16. list: Array<IDataItem>;

  17. pageNum: number;

  18. pageSize: number;

  19. total: number;

  20. }

  21. // 请求

  22. export const getDatalist = (

  23. params: Record<string, any>

  24. ): Promise<IRes<IDataInfo>> => {

  25. return Http.get("/api/data/list", params);

  26. };

如上面代码,当我们的interface定义完成后,我们的页面数据基本都已清楚,直接写页面就会清晰很多,且出错概率会大大降低。

对于Vue3和Ts的心得和思考的更多相关文章

  1. 快速新建并配置一个eslint+prettier+husky+commitlint+vue3+vite+ts+pnpm的项目

    前置准备 一台电脑 vscode pnpm vscode插件:ESLint v2.2.6及以上 vscode插件:Prettier - Code formatter v9.5.0及以上 vscode插 ...

  2. node+ts的心得与坑

    首先先明确,用node+ts的目的,为什么不ng+ts.这一点后面还会反复提醒自己 node毕竟不是ng. 用node的理由: 处理js,在后端操纵dom,读写类html格式的东西,比直接用py的后端 ...

  3. 【长期更新】Leetcode刷题心得与思考

    1.递归与动态规划的思考 Leetcode第95题 递归问题最重要的问题是想明白函数的作用是什么? 这个例子中函数的返回值就是给定a-b这个区间的数字,返回它所有可能的Tree,此时你不需要明白具体怎 ...

  4. vue3.0+ts+setup语法糖props写法

    写法一 import defaultImg from '@/assets/images/defaultImg.png' const props = defineProps({ src: { type: ...

  5. vite+vue3.0+ts搭建项目

    项目git地址:https://gitee.com/suyong01/vue3-ts-template vue+ts+vite项目初始化 # npm 6.x npm init @vitejs/app ...

  6. vue2.x/vue3.0中使用ts

    vue2.x(vue-cli3)中使用ts      https://www.jianshu.com/p/3cbcdd766295 https://www.cnblogs.com/xiaohuizha ...

  7. 抛弃vuex ,拥抱ts,手撸泛型Store<T>!

    前段时间学习了下vue3 和ts ,就尝试下做了个项目,结果发现vuex和ts几乎无法结合,越写越别扭,开始怀疑用ts就是自己给自己挖坑,然后加了几个vue相关的群,去抱怨了几句,得到大佬指点:你可以 ...

  8. [Vue]浅谈Vue3组合式API带来的好处以及选项API的坏处

    前言 如果是经验不够多的同志在学习Vue的时候,在最开始会接触到Vue传统的方式(选项式API),后边会接触到Vue3的新方式 -- 组合式API.相信会有不少同志会陷入迷茫,因为我第一次听到新的名词 ...

  9. vue3 区别于 vue2 的“与众不同”

    希望本篇文章能帮你加深对 Vue 的理解,能信誓旦旦地说自己熟练Vue2/3.除此之外,也希望路过的朋友可以帮助我查漏补缺.   区别 生命周期的变化 整体来看,变化不大,只是名字大部分需要 + on ...

  10. vue3 迫不得已我硬着头皮查看了keepalive的源代码,解决了线上的问题

    1.通过本文可以了解到vue3 keepalive功能 2.通过本文可以了解到vue3 keepalive使用场景 3.通过本文可以学习到vue3 keepalive真实的使用过程 4.通过本文可以学 ...

随机推荐

  1. 再谈BOM和DOM(5):各个大流浪器DOM和BOM里面的那些坑—兼容性

    三大不冒泡事件 所有浏览器的focus/blur事件都不冒泡,万幸的是大部分浏览器支持focusin/focusout事件,不过可恶的firefox连这个都不支持. IE6.7.8下 submit事件 ...

  2. 如何用Xcode安装ipa

    Xcode安装ipa iOS APP上架App Store其中一个步骤就是要把ipa文件上传到App Store!​ 下面进行步骤介绍!​ 利用Appuploader这个软件,可以在Windows.L ...

  3. 火山引擎在行为分析场景下的ClickHouse JOIN优化

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 背景 火山引擎增长分析DataFinder基于ClickHouse来进行行为日志的分析,ClickHouse的主要 ...

  4. 火山引擎 DataLeap 构建Data Catalog系统的实践(二):技术与产品概览

    技术与产品概览 架构设计 元数据的接入 元数据接入支持T+1和近实时两种方式 上游系统:包括各类存储系统(比如Hive. Clickhouse等)和业务系统(比如数据开发平台.数据质量平台等) 中间层 ...

  5. WxJava for Solon - 咱也不知道为啥要写

    ? 应 Solon 技术交流群里小伙伴的要求,我分享下在 Solon 中使用 WxJava 的经验.类库. 具体实现 提供统一的 Yaml 配置 package cn.edu.hnuahe.mount ...

  6. 巧用别名和 sh 脚本,adb 快速截图和录屏,提高你的效率

    前言 在平时开发过程中,我们经常需要截图和录制视频,尤其是客户端开发和测试. 可能有一些人的姿势是这样的.在电脑上开个模拟器,使用第三方工具后进行截图和录屏.还有一种最原始的方式,在手机上截图和录制视 ...

  7. VMware Workstation centos7 虚拟机桥接方式联网,获取动态IP

    在VMware中安装 Centos7 虚拟机,日常需要带着电脑外出.因此在远程连接虚拟机时,就要求与宿主机在同一网段.在不修改路由器的情况下,让宿主与centos7都动态从路由器获取IP地址,就能解决 ...

  8. 图扑虚拟现实解决方案,实现 VR 数智机房

    前言 如今,虚拟现实技术作为连接虚拟世界和现实世界的桥梁,正加速各领域应用形成新场景.新模式.新业态. 效果展示 图扑软件基于自研可视化引擎 HT for Web 搭建的 VR 数据中心机房,是将数据 ...

  9. java bean和String之间相互转化

    开发中有的表字段特别多,在数据传递过程中要写很多类似实体类的get.set方法把字符串型的数据放到对象里然后,在做存储之类的操作,如果实体的字段少不会觉得多麻烦,但是字段如果有几十个或者更多那么这种简 ...

  10. div模拟表格单元格合并

    效果如下图: html代码如下: 1 <ul class="schedule-list"> 2 <li class="schedule-title&qu ...