Vue 3 Composition API - “ref”和“reactive”

介绍

随着 Vue 3 的发布,开发人员现在可以访问 Composition API,这是一种编写 Vue 组件的新方法。此 API 允许将功能按逻辑分组在一起,而不必按功能组织单文件组件。使用 Composition API 可以产生更易读的代码,并在开发应用程序时为开发人员提供更大的灵活性。

Composition API 提供了两种不同的方式来在组件中本地存储数据——“ref”和“reactive”。这两种方法的作用类似于当今 Vue 应用程序中常用的传统 Options API 中的“数据”函数。在本文中,我们将探讨这两种新方法,以及何时在您自己的应用程序中使用它们。

选项 API -data

如果您过去使用过 Vue,您可能已经看到组件的不同部分是如何按功能划分的。每个单文件组件都可以访问许多属性:数据、计算、方法、生命周期挂钩等。这称为“选项 API”。下面是一个使用 Options API 实现本地状态的示例应用程序:


<template>
  <button @click="count++">count is: {
    
    { count }}</button>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "App",
  data() {
    return {
      count: 0
    };
  }
});
</script>

组合 API -ref

现在让我们看一下与上面相同的示例,使用 Composition API。首先,我们来看看ref来自 Vue 3 文档

ref 接受一个内部值并返回一个反应性和可变的 ref 对象。ref 对象有一个属性 .value 指向内部值。

下面是我们使用的示例代码ref


<template>
  <button @click="count++">count is: {
    
    { count }}</button>
</template>

<script lang="ts">
import { ref, defineComponent } from "vue";

export default defineComponent({
  name: "App",
  setup: () => {
    const count = ref(0);

    return { count };
  },
});
</script>

让我们仔细看看。这两个例子之间有什么变化?

  1. 我们不是使用data函数来添加本地状态,而是使用setup函数。这个新函数取代了databeforeCreate、 和created,并且是使用 Composition API 的地方。
  2. 与 一样datasetup返回一个对象。该对象的内容是需要从模板访问的任何变量。由于我们希望计数在模板中可用,因此我们将其包含在返回对象中。

在我们继续之前reactive,我们应该再做一个改变。让我们将 click 事件移动到它自己的方法中,而不是在模板中执行操作。


<template>
  <button @click="increaseCount">count is: {
    
    { count }}</button>
</template>

<script lang="ts">
import { ref, defineComponent } from "vue";

export default defineComponent({
  name: "App",
  setup: () => {
    const count = ref(0);

    const increaseCount = () => {
      count.value++;
    }

    return { count, increaseCount };
  },
});
</script>

与 Options API 不同,方法只是函数。我们不需要任何特殊的语法或组合 API 方法来使它们工作。但是,就像count上面的变量一样,我们确实需要从函数中返回方法setup,以便它在模板中可用。

请注意,在模板中,我们曾经count++增加值,但在setup函数中,我们使用count.value. 这是因为在setup函数中,count有一个 类型Ref<number>,在模板中内部值是直接可用的。

组合 API -reactive

现在让我们试试这个reactive方法。来自 Vue 3 文档

反应式返回对象的反应式副本。反应式转换是“深度”的——它影响所有嵌套的属性。在基于ES2015 Proxy的实现中,返回的代理不等于原始对象。建议只使用响应式代理,避免依赖原始对象。

reactive这是我们使用代替的代码示例ref


<template>
  <button @click="increaseCount">count is: {
    
    { state.count }}</button>
</template>

<script lang="ts">
import { reactive, defineComponent } from "vue";

export default defineComponent({
  name: "App",
  setup: () => {
    const state = reactive({
      count: 0
    });

    const increaseCount = () => {
      state.count++;
    }

    return { state, increaseCount };
  },
});
</script>

setup函数中,我们可以使用 的返回值,这与我们在 Options API 中reactive使用函数的方式非常相似。data因为对象具有深度反应性,我们也可以直接对其进行更改。count.value++因此,我们可以简单地用 增加值来代替state.value++

何时使用refreactive

一般而言,ref对原语(字符串、数字、布尔值等)reactive很有用,对对象和数组也很有用。但是,有一些关键点需要考虑:

首先,如果您将一个对象传递给ref函数调用,它将返回一个已通过的对象reactive。下面的代码工作得很好:


<template>
  <button @click="increaseCount">count is: {
    
    { state.count }}</button>
</template>

<script lang="ts">
import { ref, defineComponent } from "vue";

export default defineComponent({
  name: "App",
  setup: () => {
    const state = ref({
      count: 0
    });

    const increaseCount = () => {
      state.value.count++;
    }

    return { state, increaseCount };
  },
});
</script>

其次,虽然从返回的对象reactive是高度反应性的(为对象设置任何值都会触发 Vue 中的反应),但您仍然可能意外地使这些值成为非反应性的。例如,如果您尝试解构或传播对象的值,它们将不再是反应性的。下面的代码不像你预期的那样工作


<template>
  <button @click="increaseCount">count is: {
    
    { count }}</button>
</template>

<script lang="ts">
import { reactive, defineComponent } from "vue";

export default defineComponent({
  name: "App",
  setup: () => {
    const state = reactive({
      count: 0
    });

    const increaseCount = () => {
      state.count++;
    }

    return { ...state, increaseCount };
  },
});
</script>

如果你想做这样的事情,Vue 3 可以满足你。有许多函数可以在 Refs 和它们的值之间进行转换。在这种情况下,我们将使用该toRefs函数。从文档:

将响应式对象转换为普通对象,其中结果对象的每个属性都是指向原始对象相应属性的 ref。

如果我们更新上面的代码示例来传播 的结果toRefs,那么一切都会像我们预期的那样工作:


<template>
  <button @click="increaseCount">count is: {
    
    { count }}</button>
</template>

<script lang="ts">
import { toRefs, reactive, defineComponent } from "vue";

export default defineComponent({
  name: "App",
  setup: () => {
    const state = reactive({
      count: 0
    });

    const increaseCount = () => {
      state.count++;
    }

    return { ...toRefs(state), increaseCount };
  },
});
</script>

还有其他方法可以组合这两个函数,既可以将reactive对象中的值设置为它自己的变量,toRef也可以直接将 a 添加ref到对象中。refreactive是解决方案的两个部分,您会发现自己根据需要接触到每个部分。

结论

Vue 3 Composition API 为开发人员提供了很多好处。通过允许将功能而不是功能组合在一起,开发人员可以专注于他们正在构建的内容,而不是将他们的代码装配到预定的结构中。

通过利用refreactive函数来维护本地状态,开发人员可以使用新工具来编写更易维护和可读的代码。这些方法可以很好地协同工作,而不是一种或另一种,每种方法都解决了不同的问题。

请记住,Composition API 是可选的!现有的 Options API 不会去任何地方,并将继续按预期工作。我会鼓励您尝试 Composition API,看看这些新方法如何改进您自己的工作流程和应用程序。

猜你喜欢

转载自blog.csdn.net/qq_22182989/article/details/125398691