Vue 3.0 中令人激动的新功能:Composition API

正如你所期望的那样,Vue 3带来了很多令人兴奋的新功能。值得庆幸的是,Vue团队主要是在当前API的基础上引入了一些补充和改进,而不是进行重大更改,所以已经了解Vue 2的人应该很快就会对新的语法感到适应。

让我们从你们大多数人可能听说过的API开始吧......

Composition API

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

当前,我们使用所谓的Options API构建组件。为了向Vue组件添加逻辑,我们填充(选项)属性,例如数据,方法,计算的等。这种方法的最大缺点是,这本身并不是有效的JavaScript代码。您需要确切了解模板中可以访问哪些属性,以及此关键字的行为。在后台,Vue编译器需要将此属性转换为工作代码。因此,我们无法从自动建议或类型检查中受益。

Composition API的目的是通过将当前可用组件属性作为JavaScript函数暴露出来的机制来解决这个问题。Vue核心团队将Composition API描述为“一组基于功能的附加API,可以灵活地组合组件逻辑”。使用 Composition API 编写的代码更易读,而且没有任何幕后的魔力,更容易阅读和学习。

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

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

<script>
import { reactive, computed } from 'vue'

export default {
  setup() {
    const state = reactive({
      count: 0,
      double: computed(() => state.count * 2)
    })

    function increment() {
      state.count++
    }

    return {
      state,
      increment
    }
  }
}
</script>

现在,让我们把这段代码分解成几段,以了解发生了什么事

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

正如我之前提到的Component API是以函数的形式展示组件属性,所以第一步就是导入我们需要的函数。在我们的例子中,我们需要用 ref创建reactive reference,用 computed 创建computed属性,用onMounted访问mounted的挂载生命周期钩子。·

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

export default {
  setup() {}
}

简而言之,它只是一个函数,向模板返回属性和函数。就是这样。我们在这里声明所有的反应式属性、计算属性、watchers和生命周期钩子,然后返回它们,这样它们就可以在模板中使用。·

我们没有从setup函数中返回的东西将不能在模板中使用

const count = ref(0)

根据上面的内容,我们用ref函数声明了一个叫count的反应式属性。它可以包裹任何基元或对象,并返回它的反应式引用。传入的元素的值将被保存在创建的引用的value属性中。例如,如果你想访问count引用的值,你需要显式请求count.value。

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

function increment() {
  count.value++
}

而这正是我们在声明计算属性双倍和增量函数时所做的

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

当组件被挂载时,我们用onMounted钩子记录一些消息,只是为了让你知道你可以 simle

return {
  count,
  double,
  increment
}

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

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

现在我们可以像以前的Options API一样,在模板中访问由setup方法返回的属性和函数

这是一个简单的例子,用Options API也可以很容易实现。新的Composition API的真正好处不仅仅是以不同的方式编码,当涉及到重用我们的代码/逻辑时,好处就会显现出来

使用Composition API重用代码

新的Composition API有更多的优势。考虑到代码的重用。目前,如果我们想在其他组件之间共享一些代码,有两种选择----mixins和scoped slots。这两种方案都有其缺点。

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

让我们从mixins开始说起

import CounterMixin from './mixins/counter'

export default {
  mixins: [CounterMixin]
}

mixins最大的缺点是,我们对它究竟在我们的组件中加入了什么东西一无所知。这使得它不仅难以推理,而且还可能导致与现有的属性和函数的名称碰撞。·

这时候就到了加scoped slots的时候了

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

有了scoped slots,我们就可以通过v-slot属性准确地知道我们可以通过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
    }
  }
}

更加优雅了,不是吗?我们不受模板和组件范围的限制,可以准确地知道我们可以从counter中访问哪些属性。此外,我们还可以从编辑器中的代码完成中受益,因为useCounter只是一个返回一些属性的函数。在幕后没有什么魔法,所以编辑器可以帮助我们进行类型检查和建议。

这也是一种比较优雅的使用第三方库的方式。例如,如果我们想使用Vuex,我们可以显式使用Store函数,而不是污染Vue原型(this.$store)。这种方法也消除了Vue插件的幕后魔法

const { commit, dispatch } = useStore()

如果你想了解更多关于Composition API和它的用例,我强烈推荐你阅读Vue团队的这篇文档,它解释了新的API背后的原因,并推荐了它的最佳用例。还有一个很好的资源库,里面有Vue核心团队的Thorsten Lünborg提供的Composition API使用案例

以上示例来自:https://composition-api.vuejs.org/#basic-example

上一篇:动态SQL详解


下一篇:使用组合(java)时如何实现关闭开关?