Vue 3 Composition API实战前瞻

Posted 前端之巅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue 3 Composition API实战前瞻相关的知识,希望对你有一定的参考价值。

作者|Mateusz Rybczonek
译者|王强
编辑|王文婧
虽然 Vue3.0 尚未发布,但前段时间,Vue 发布了关于 Composition API 的官方插件。本文作者通过实际试用,对 Composition API 与当前的 Options API 作出了一番对比,并对 Composition API 的特征与用途进行了通俗易懂的总结。一起来看看!

我最近得到了机会,在一个真实的项目中试用了 Vue 中全新的 Composition API,进而对它可能的用途以及未来的用法探索了一番。

现在,当我们创建一个新组件时使用的是 Options API。使用这个 API 时,我们必须通过选项将组件的代码分离开来,这意味着我们需要将所有响应性数据放在一个地方,所有计算的属性放在一个位置,所有方法也都放在一个位置,依此类推。

这个 API 在处理较小的组件时比较易读和顺手,而当组件变得更加复杂,需要处理多种功能时,它用起来就很痛苦了。一般来说,与一个特定功能相关的逻辑会包含一些响应性数据、一些计算属性,还有一种或一些方法。有时还会用到组件生命周期 hooks。于是在处理单个逻辑问题时,需要不断在代码中的不同选项之间来回切换。

使用 Vue 时,可能遇到的另一个问题是设法提取可被多个组件复用的通用逻辑。Vue 已经提供了一些方案可供选择,但它们都有各自的缺点(例如 mixins 和作用域插槽)。而新的 Composition API 带来了一种创建组件、分离代码和提取可复用代码段的全新方式。

首先来看组件内的代码构成。

代码构成
假设你有一个核心组件,为整个 Vue 应用设置了一些内容(就像 Nuxt 中的布局)。它负责处理以下内容:
  • 设定区域;
  • 检查用户是否处于登录状态,如果没有,则将其重定向;
  • 防止用户重新加载应用程序太多次数;
  • 跟踪用户活动,并在用户静默一段时间后做出反应;
  • 使用 EventBus 监听事件(或窗口对象事件)。

这些只是这个组件可以做的事情的一些例子。你可能会设想出一个更复杂的组件,不过这里的这些已经足够本文举例说明了。为了便于阅读,我只用了 props 的名称,而没有实际实现。

下面是使用 Options API 时组件的样子:
<template>
  <div id="app">
    ...
  </div>
</template>

<script>
export default {
  name: 'App',

  data() {
    return {
      userActivityTimeout: null,
      lastUserActivityAt: null,
      reloadCount: 0
    }
  },

  computed: {
    isAuthenticated() {...}
    locale() {...}
  },

  watch: {
    locale(value) {...},
    isAuthenticated(value) {...}
  },

  async created() {
    const initialLocale = localStorage.getItem('locale')
    await this.loadLocaleAsync(initialLocale)
  },

  mounted() {
    EventBus.$on(MY_EVENT, this.handleMyEvent)

    this.setReloadCount()
    this.blockReload()

    this.activateActivityTracker()
    this.resetActivityTimeout()
  },

  beforeDestroy() {
    this.deactivateActivityTracker()
    clearTimeout(this.userActivityTimeout)
    EventBus.$off(MY_EVENT, this.handleMyEvent)
  },

  methods: {
    activateActivityTracker() {...},
    blockReload() {...},
    deactivateActivityTracker() {...},
    handleMyEvent() {...},
    async loadLocaleAsync(selectedLocale) {...}
    redirectUser() {...}
    resetActivityTimeout() {...},
    setI18nLocale(locale) {...},
    setReloadCount() {...},
    userActivityThrottler() {...},
  }
}
</script>

如你所见,每个选项都包含所有功能的其中一部分。它们之间没有明确的分隔,这使代码很难阅读。如果代码并不是你写的,你还是第一次看到它,那么读起来会更费劲,很难分清具体哪种功能使用的是哪种方法。

我们再来看一下,但这次用注释把逻辑上的关注点标识出来。这些关注点包括:
  • Activity Tracker(活动追踪);
  • Reload Blocker(阻止重新加载);
  • Authentication check(登录状态检查);
  • Locale(区域选项);
  • Event Bus Registration(EventBus 注册)。


<template>
  <div id="app">
    ...
  </div>
</template>

<script>
export default {
  name: 'App',

  data() {
    return {
      userActivityTimeout: null, // Activity tracker
      lastUserActivityAt: null, // Activity tracker
      reloadCount: 0 // Reload blocker
    }
  },

  computed: {
    isAuthenticated() {...} // Authentication check
    locale() {...} // Locale
  },

  watch: {
    locale(value) {...},
    isAuthenticated(value) {...} // Authentication check
  },

  async created() {
    const initialLocale = localStorage.getItem('locale') // Locale
    await this.loadLocaleAsync(initialLocale) // Locale
  },

  mounted() {
    EventBus.$on(MY_EVENT, this.handleMyEvent) // Event Bus registration

    this.setReloadCount() // Reload blocker
    this.blockReload() // Reload blocker

    this.activateActivityTracker() // Activity tracker
    this.resetActivityTimeout() // Activity tracker
  },

  beforeDestroy() {
    this.deactivateActivityTracker() // Activity tracker
    clearTimeout(this.userActivityTimeout) // Activity tracker
    EventBus.$off(MY_EVENT, this.handleMyEvent) // Event Bus registration
  },

  methods: {
    activateActivityTracker() {...}, // Activity tracker
    blockReload() {...}, // Reload blocker
    deactivateActivityTracker() {...}, // Activity tracker
    handleMyEvent() {...}, // Event Bus registration
    async loadLocaleAsync(selectedLocale) {...} // Locale
    redirectUser() {...} // Authentication check
    resetActivityTimeout() {...}, // Activity tracker
    setI18nLocale(locale) {...}, // Locale
    setReloadCount() {...}, // Reload blocker
    userActivityThrottler() {...}, // Activity tracker
  }
}
</script>

由此可见,解开这团乱麻有多复杂。

以上是关于Vue 3 Composition API实战前瞻的主要内容,如果未能解决你的问题,请参考以下文章

VUE3.x 前瞻

如何跨多个文件中的多个 Vue 实例正确使用 Vue 3 composition-api

vue2升级vue3: TSX Vue 3 Composition API Refs

为啥在 Vue 3 的 Composition API 中使用“API”这个词?

Vue3新特性——Composition API详解

Vue 3 Composition API - watchEffect 与 watch