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

news/2024/7/5 10:45:47

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

Composition API 解决了什么问题

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

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

  • 代码的可读性随着组件变大而变差
  • 每一种代码复用的方式,都存在缺点
  • TypeScript支持有限

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

Options Api 选项式API

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

如下代码:

export default {
  name: '',
  props: {
    
  },
  components: { },
  computed: { },
  data() {
    return {

    }
  },
  created() {
      
  },
  methods: {

  },
  watch: {
        
  }
}

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

用组件的选项( data 、 computed 、 methods 、 watch ) 组织逻辑在大多数情况下都有效,然而,当组件变得复杂,导致对应属性的列表也会增长,这可能会导致组件难以阅读和理解。

Composition Api 组合式API

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

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

两者对比

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

  • 逻辑组织
  • 逻辑复用

逻辑组织

  • 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 在逻辑组织方面的优势,以后修改一个属性功能的时候,只需要跳到控制该属性的方法中即可。

逻辑复用

在 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 API 对 tree-shaking 友好,代码也更容易压缩
  • Composition API 中见不到 this 的使用,减少了 this 指向不明的情况
  • 如果是小型组件,可以继续使用 Options API ,也是十分友好的

http://lihuaxi.xjx100.cn/news/1931458.html

相关文章

第二十七章 正则表达式

第二十七章 正则表达式 1.正则快速入门2.正则需求问题3.正则底层实现14.正则底层实现25.正则底层实现36.正则转义符7.正则字符匹配8.字符匹配案例19.字符匹配案例211.选择匹配符&#xff08;|&#xff09;12.正则限定符{n}{n,m}&#xff08;1个或者多个&#xff09;*(0个或者多…

力扣42. 接雨水

双指针法 思路&#xff1a; 将数组前后设置为 left、right 指针&#xff0c;相互靠近&#xff1b;在逼近的过程中记录两端最大的值 leftMax、rightMax&#xff0c;作为容器的左右边界&#xff1b;更新指针规则&#xff1a; 如果数组左边的值比右边的小&#xff0c;则更新 left…

Python中的协程、线程和进程

一.协程与多线程和多进程一起使用有什么不同 协程、多线程和多进程都是实现程序并发执行的方法&#xff0c;不过它们在工作方式和适合的应用场景上存在一些区别。 1.协程&#xff08;Coroutine&#xff09; 协程是在单一线程内部实现并发的&#xff0c;由于只涉及单一线程&…

Spring Boot 如何使用 Maven 实现多环境配置管理

Spring Boot 如何使用 Maven 实现多环境配置管理 实现多环境配置有以下几个重要原因&#xff1a; 适应不同的部署环境&#xff1a;在实际部署应用程序时&#xff0c;通常会有多个不同的部署环境&#xff0c;如开发环境、测试环境、生产环境等。每个环境可能需要不同的配置&…

【算法题】33. 搜索旋转排序数组

题目 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], ..., nums[n-1], nums[0], nums[…

20 太空漫游

效果演示 实现了一个太空漫游的动画效果&#xff0c;其中包括火箭、星星和月亮。当鼠标悬停在卡片上时&#xff0c;太阳和星星会变成黄色&#xff0c;火箭会变成飞机&#xff0c;月亮会变成小型的月亮。整个效果非常炫酷&#xff0c;可以让人想起科幻电影中的太空漫游。 Code &…

几个实用网站

论文短语&#xff1a;https://www.phrasebank.manchester.ac.uk/ 翻译&#xff1a;https://www.deepl.com/en/translator 润色&#xff1a;https://quillbot.com/ 榜单&#xff1a;www.paperwithcode.com ****NLP民工的乐园: 几乎最全的中文NLP资源库&#xff1a;****https…

基于STM32+QT设计的无人超市消费系统_139

基于STM32+QT设计的无人超市消费系统 一、前言 1.1 研究背景 随着科学技术的不断提高,计算机科学日渐成熟,其强大的功能已为人们深刻认识,它已进入人类社会的各个领域并发挥着越来越重要的作用。 超市形式在我国于20世纪90年代初期起步,现已成为我国零售业的一种重要形态…