为你解读Vue3中的大热门——Composition API

作者:Filip Rakowski

翻译:启道学院


我们已经知道,在Vue的新版本中编写的应用程序将表现得非常好,但性能并不是最重要的部分。 对我们开发人员来说最重要的是新版本将如何影响我们编写代码的方式。

正如你所预料的,Vue3带来了许多新的振奋人心的功能。 幸运的是,Vue团队主要对当前的Composition API进行了添加和改进,而不是进行了重大更改,因此已经知道Vue2的人应该很快对新的语法感到满意。

让我们从大多数人可能听说的Composition API开始!

Composition API

下一个主要版本的Vue中讨论的最常见的就是Composition AP的特色语法的。 这是一种全新的逻辑重用和代码组织方法。

目前,我们使用的是“options”API 构建组件。 为了将逻辑添加到Vue组件中,我们填充(options)属性,如data、methods、computed等。 这种方法最大的缺点是,它本身不是一个工作的JavaScript代码。 您需要确切地知道模板中可以访问哪些属性以及this关键字的行为。在底层,Vue编译器需要将此属性转换为工作代码。正因为如此,我们无法从自动建议或类型检查中获益。

Composition API希望将通过当前组件属性、可用的机制公开为JavaScript函数来解决这个问题。 Vue核心团队将组件Composition API描述为“一套附加的、基于函数的api,允许灵活地组合组件逻辑”。 使用Composition API编写的代码更易读,并且场景不复杂,这使得阅读和学习变得更容易。

让我们看到一个非常简单的组件示例,它使用新的组件Composition API来理解它是如何工作的。

<template>
  <button @click="increment">
    Count is: {{ count }}, double is {{ double }}, click to increment.
  </button>
</template>

<script>
import { ref, computed, onMounted } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const double = computed(() => count.value * 2)

    function increment() {
      count.value++
    }

    onMounted(() => console.log('component mounted!'))

    return {
      count,
      double,
      increment
    }
  }
}
</script>

现在让我们把这个代码分解成几个版块来理解发生了什么。

import { ref, computed, onMounted } from 'vue'

正如我前面提到的,Composition API将组件属性公开为函数,因此第一步是导入我们需要的函数。 在案例中,我们需要用ref创建响应式引用、计算属性使用computed、用onMounted访问装载后的生命周期钩子。

现在你可能想知道这个神秘的setup方法是什么?

export default {
  setup() {}
	}
	```
简而言之,它只是一个函数,它将属性和函数返回到模板。  我们在这里声明所有的响应式属性、计算属性、观察者和生命周期钩子,然后返回它们,以便它们可以在模板中使用。 我们没有在setup函数返回的内容将在模板中不可用。 

```js
const count = ref(0)

根据上面的内容,我们将用ref函数声明称为count的响应式属性。 它可以包装任何原始类型或对象,并返回它的响应式引用。 传递元素的值将保留在创建引用的值属性中。 例如,如果要访问count引用的值,则需要扩展请求count.value.

const double = computed(() => count.value * 2)

function increment() {
  count.value++
}

这是我们在声明计算属性double和increment函数时所做的事

onMounted(() => console.log('component mounted!'))

在mounted钩子内,当组件装载时,你可以记录一些消息

return {
  count,
  double,
  increment
}

在最后,我们返回count和double属性与increment方法,使它们在模板中可用。

<template>
  <button @click="increment">
    Count is: {{ count }}, double is {{ double }}. Click to increment.
  </button>
</template>

现在,我们可以在template中访问setup返回的属性和函数,就像它们通过旧的options API声明的一样。

这是一个简单的例子,使用Options API也很容易实现这一点。新的Composition API的真正好处不仅在于以不同的方式编写代码,而且在重用我们的代码/逻辑时,这些好处也会显现出来。

Composition API代码重用

新的Composition API有更多的优点。 想想代码重用, 目前,如果我们想在其他组件之间共享一些代码,有两个可用的选择--混入 和 范围插槽。 两者都有其缺点。

假设我们想要提取count功能并在其他组件中重用它,下面您可以看到它如何与可用的API和Composition API一起使用。

我们从混入开始……

import CounterMixin from './mixins/counter'

export default {
  mixins: [CounterMixin]
}

混入最大的缺点:是我们不知道它给我们的组件增加了什么。 它不仅难以解释,而且还可能导致与现有属性和函数的名称冲突。

看看范围插槽

<template>
  <Counter v-slot="{ count, increment }">
     {{ count }}
    <button @click="increment">Increment</button> 
  </Counter> 
</template>

使用范围插槽,我们确切地知道我们可以通过v-slot属性访问哪些属性,这样就更容易理解代码了。 这种方法的缺点是,我们只能在模板中访问它,它只能在Counter组件范围内使用。

是时候使用Composition API了

function useCounter() {
  const count = ref(0)
  function increment () { count.value++ }

  return {
    count,
    incrememt
  }
}

export default {
  setup () {
    const { count, increment } = useCounter()
    return {
      count,
      increment
    }
  }
}

更优雅,不是吗? 我们不受模板和组件范围的限制,并且确切地知道我们可以从计数器访问哪些属性。 此外,我们可以从编译完成的代码中受益,因为useCounter只是一个返回某些属性的函数。 所以编辑器可以帮助我们进行类型检查和建议。

这也是使用第三方库的一种更优雅的方式。例如,如果我们想使用vuex,我们可以扩展useStore函数而不是污染Vue原型(this.$store)。

const { commit, dispatch } = useStore()
posted @ 2020-03-22 15:54  凃老师  阅读(5077)  评论(0编辑  收藏  举报