Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

凯特林 等级 585 0 0
标签: api前端

Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

开始之前

Composition API 可以说是Vue3最大的特点,那么为什么要推出Composition Api,解决了什么问题?

通常使用Vue2开发的项目,普遍会存在以下问题:

  • 代码的可读性随着组件变大而变差

  • 每一种代码复用的方式,都存在缺点

  • TypeScript支持有限

以上通过使用Composition Api都能迎刃而解

正文

一、Options Api

Options API,即大家常说的选项API,即以vue为后缀的文件,通过定义methodscomputedwatchdata等属性与方法,共同处理页面逻辑

如下图:

Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

可以看到Options代码编写方式,如果是组件状态,则写在data属性上,如果是方法,则写在methods属性上...

用组件的选项 (datacomputedmethodswatch) 组织逻辑在大多数情况下都有效

然而,当组件变得复杂,导致对应属性的列表也会增长,这可能会导致组件难以阅读和理解

二、Composition Api

在 Vue3 Composition API 中,组件根据逻辑功能来组织的,一个功能所定义的所有 API 会放在一起(更加的高内聚,低耦合)

即使项目很大,功能很多,我们都能快速的定位到这个功能所用到的所有 API

Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

三、对比

下面对Composition ApiOptions Api进行两大方面的比较

  • 逻辑组织

  • 逻辑复用

逻辑组织

Options API

假设一个组件是一个大型组件,其内部有很多处理逻辑关注点(对应下图不用颜色)

Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

可以看到,这种碎片化使得理解和维护复杂组件变得困难

选项的分离掩盖了潜在的逻辑问题。此外,在处理单个逻辑关注点时,我们必须不断地“跳转”相关代码的选项块

Compostion API

Compositon API正是解决上述问题,将某个逻辑关注点相关的代码全都放在一个函数里,这样当需要修改一个功能时,就不再需要在文件中跳来跳去

下面举个简单例子,将处理count属性相关的代码放在同一个函数了

function useCount() {  
    let count = ref(10);  
    let double = computed(() => {  
        return count.value * 2;  
    });  

    const handleConut = () => {  
        count.value = count.value * 2;  
    };  

    console.log(count);  

    return {  
        count,  
        double,  
        handleConut,  
    };  
}  

组件上中使用count

export default defineComponent({  
    setup() {  
        const { count, double, handleConut } = useCount();  
        return {  
            count,  
            double,  
            handleConut  
        }  
    },  
});  

再来一张图进行对比,可以很直观地感受到 Composition API在逻辑组织方面的优势,以后修改一个属性功能的时候,只需要跳到控制该属性的方法中即可

Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

逻辑复用

Vue2中,我们是用过mixin去复用相同的逻辑

下面举个例子,我们会另起一个mixin.js文件

export const MoveMixin = {  
  data() {  
    return {  
      x: 0,  
      y: 0,  
    };  
  },  

  methods: {  
    handleKeyup(e) {  
      console.log(e.code);  
      // 上下左右 x y  
      switch (e.code) {  
        case "ArrowUp":  
          this.y--;  
          break;  
        case "ArrowDown":  
          this.y++;  
          break;  
        case "ArrowLeft":  
          this.x--;  
          break;  
        case "ArrowRight":  
          this.x++;  
          break;  
      }  
    },  
  },  

  mounted() {  
    window.addEventListener("keyup", this.handleKeyup);  
  },  

  unmounted() {  
    window.removeEventListener("keyup", this.handleKeyup);  
  },  
};  

然后在组件中使用

<template>  
  <div>  
    Mouse position: x {{ x }} / y {{ y }}  
  </div>  
</template>  
<script>  
import mousePositionMixin from './mouse'  
export default {  
  mixins: [mousePositionMixin]  
}  
</script>  

使用单个mixin似乎问题不大,但是当我们一个组件混入大量不同的 mixins 的时候

mixins: [mousePositionMixin, fooMixin, barMixin, otherMixin]  

会存在两个非常明显的问题:

  • 命名冲突

  • 数据来源不清晰

现在通过Compositon API这种方式改写上面的代码

import { onMounted, onUnmounted, reactive } from "vue";  
export function useMove() {  
  const position = reactive({  
    x: 0,  
    y: 0,  
  });  

  const handleKeyup = (e) => {  
    console.log(e.code);  
    // 上下左右 x y  
    switch (e.code) {  
      case "ArrowUp":  
        // y.value--;  
        position.y--;  
        break;  
      case "ArrowDown":  
        // y.value++;  
        position.y++;  
        break;  
      case "ArrowLeft":  
        // x.value--;  
        position.x--;  
        break;  
      case "ArrowRight":  
        // x.value++;  
        position.x++;  
        break;  
    }  
  };  

  onMounted(() => {  
    window.addEventListener("keyup", handleKeyup);  
  });  

  onUnmounted(() => {  
    window.removeEventListener("keyup", handleKeyup);  
  });  

  return { position };  
}  

在组件中使用

<template>  
  <div>  
    Mouse position: x {{ x }} / y {{ y }}  
  </div>  
</template>  

<script>  
import { useMove } from "./useMove";  
import { toRefs } from "vue";  
export default {  
  setup() {  
    const { position } = useMove();  
    const { x, y } = toRefs(position);  
    return {  
      x,  
      y,  
    };  

  },  
};  
</script>  

可以看到,整个数据来源清晰了,即使去编写更多的 hook 函数,也不会出现命名冲突的问题

小结

  • 在逻辑组织和逻辑复用方面,Composition API是优于Options API

  • 因为Composition API几乎是函数,会有更好的类型推断。

  • Composition APItree-shaking 友好,代码也更容易压缩

  • Composition API中见不到this的使用,减少了this指向不明的情况

  • 如果是小型组件,可以继续使用Options API,也是十分友好的

收藏
评论区

相关推荐

Vue3.0--Vue Composition API使用体验
本文将之前采用Vue2.6开发的todoList小项目改造成为Vue3.0编写,并介绍一下2.x和3.x之间写法的不同之处。 Vue3.x适配大部分Vue2.x的组件配置,也就是说以前我们在Vue2.x针对组件的一些配置项,例如: export default { name: 'test', components: {}, props: {},
Swift与Objective-C混合编程之Swift与Objective-C API映射
原创文章,欢迎转载。转载请注明:关东升的博客 Swift与ObjectiveC API映射 在混合编程过程中Swift与ObjectiveC调用是双向的,由于不同语言对于相同API的表述是不同的,他们之间是有某种映射规律的,这种API映射规律主要体现在构造函数和方法两个方面。 1、构造函数映射 在Swift与ObjectiveC语言进行混合
Vue3 的 15 个常用 API
来自公众号:前端印象 本文会频繁地对比Vue2来介绍Vue3,也将对各个API结合代码实例讲解,这既是对自己知识的总结,也希望能帮助到大家 一、前言 大家都知道,现在Vue3的各个版本已经陆续发布了,并且有很多的团队已经着手各个库的开发与Vue2向Vue3的升级,我们当然也不能落后,所以赶紧将你手中的Vue2升级到Vue3,跟着本文一起学
Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
开始之前 Composition API 可以说是Vue3最大的特点,那么为什么要推出Composition Api,解决了什么问题? 通常使用Vue2开发
笔趣阁小说api
笔趣阁api小说api,提供小说相关api接口,目前支持笔趣阁(https://m.bqkan.com/)。ip地址:http://49.234.123.245:8082 笔趣阁(https://m.bqkan.com/) 1. 首页 ip/getHome 2. 小说分类 ip/
Vue3 + Vuex4 构建点餐页面
前言 前进!前进!不择手段地前进!!距离Vue3.0 beta 发布已经过了半个多月了。本来这个东西上个月就应该写了,由于公司上个月赶项目一直没时间。趁着劳动节把这个东西写了一下,也顺便把一些坑过了一下。 介绍页面比较简单,算是把 Composition API 过了一下了 基于Vue3.0 beta 这种页面也比较老套了 涉及了
Fabric1.4:Go 链码开发与编写
1 链码结构 1.1 链码接口 链码启动必须通过调用 shim 包中的 Start 函数,传递一个类型为 Chaincode 的参数,该参数是一个接口类型,有两个重要的函数 Init 与 Invoke 。 type Chainc
基于Python的nessus API简析
前言最近在开发一个基于Nessus的自动化漏扫工具,来和大家分析一下关于Nessus API的使用心得。 Nessus提供了非常完善的API,可以帮助我们实现很多事情,无论是对接其他运维系统,还是用来编写自动化的漏扫工具都十分方便。 Nessus为这些api提供了详细的文档,你可以在SettingsMy AccountAPI KeysAP
初识Windows API
Windows API是什么 Windows系统是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务 ,就是一个函数)可以帮应用程序达到开启视窗、描绘图形、使用周边设备等,由于这些函数服务的对象是应用程序(Applicati
Fetch API 教程
Fetch API 教程作者: 日期: fetch()是 XMLHttpRequest 的升级版,用于在 JavaScript 脚本里面发出 HTTP 请求。浏览器原生提供这个对象。本文详细介绍它的用法。一、基本用法fetch()的功能与 XMLHttpRequest 基本相同,但有三个主要的差异。(1)fetc
Vue 3 计划放弃支持 IE11
Vue.js 作者尤雨溪就 Vue 3 支持 IE11 的计划提交了新提案。提案摘要:1. Vue 3 将不会支持 IE11 2. 原定投入 Vue 3 IE11 支持的精力将投入给 2.7,移植 3.x 兼容的新功能,包括: Composition API \<script setup\ 以及其它新的单文件组件特性
Vue3.0系列——「vue3.0性能是如何变快的?」
前言1. 先学习vue2.x,很多2.x内容依然保留; 2. 先学习TypeScript,vue3.0是用TS重写的,想知其然知其所以然必须学习TS。 为什么学习vue3.0? 性能比vue2.x快1.2~2倍 按需编译,体积比vue2.x更小 组合API(类似React Hook) 更好的TS支持
微信小程序体验composition-api(类似vue3)
微信小程序compositionapi用该是什么样子? 使用使用起来应该像是这个样子wxue(options) setup配置应该是包含一个setup选项是一个函数,返回的函数可以this.xxx调用,返回的数据可以this.data.xxx用到,如下import wxue, reactive from 'wxue'wxue( setup(option
美团java研发岗二面:覆盖所有面试知识点
面试真题以及解析 Web,RESTful API 在微服务中的作用是什么?微服务架构基于一个概念,其中所有服务应该能够彼此交互以构建业务功能。因此,要实现这一点,每个微服务必须具有接口。这使得 Web API 成为微服务的一个非常重要的推动者。RESTful API 基于 Web 的开放网络原则,为构建微服务架构的各个组件之间的接口提供了最合理的模型。
Ory Kratos 用户认证
为用户认证与管理系统。本文将动手实现浏览器(React+AntD)的完整流程,实际了解下它的 API 。 代码: https://github.com/ikuokuo/startorykratos 了解 Kratos 获取代码bashgit clone b v0.7.0alpha.1 depth 1 https://github.com/ory/kratos