vue3组合式函数

88 阅读2分钟

一、概念

在 Vue 应用的概念中,“组合式函数”(Composables) 是一个利用 Vue 的组合式 API 来封装和复用有状态逻辑函数

二、示例(鼠标跟踪器示例)

// mouse.js
import { ref, onMounted, onUnmounted } from 'vue'

// 按照惯例,组合式函数名以“use”开头
export function useMouse() {
  // 被组合式函数封装和管理的状态
  const x = ref(0)
  const y = ref(0)

  // 组合式函数可以随时更改其状态。
  function update(event) {
    x.value = event.pageX
    y.value = event.pageY
  }

  // 一个组合式函数也可以挂靠在所属组件的生命周期上
  // 来启动和卸载副作用
  onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.removeEventListener('mousemove', update))

  // 通过返回值暴露所管理的状态
  return { x, y }
}

在组件中使用

<script setup>
import { useMouse } from './mouse.js'

const { x, y } = useMouse()
</script>

<template>Mouse position is at: {{ x }}, {{ y }}</template>

三、异步状态示例(接收响应式状态)

// fetch.js
import { ref, watchEffect, toValue } from 'vue'

export function useFetch(url) {
  const data = ref(null)
  const error = ref(null)

  watchEffect(() => {
    // 在 fetch 之前重置状态
    data.value = null
    error.value = null
    // toValue() 将可能的 ref 或 getter 解包
    fetch(toValue(url))
      .then((res) => res.json())
      .then((json) => (data.value = json))
      .catch((err) => (error.value = err))
  })

  return { data, error }
}

toValue(url) 是在 watchEffect 回调函数的内部调用的。这确保了在 toValue() 规范化期间访问的任何响应式依赖项都会被侦听器跟踪。

这个 useFetch() 现在能接收静态 URL 字符串、ref 和 getter,使其更加灵活。watch effect 会立即运行,并且会跟踪 toValue(url) 期间访问的任何依赖项。如果没有跟踪到依赖项(例如 url 已经是字符串),则 effect 只会运行一次;否则,它将在跟踪到的任何依赖项更改时重新运行。

四、限制

组合式函数只能在 <script setup> 或 setup() 钩子中被调用。在这些上下文中,它们也只能被同步调用。在某些情况下,你也可以在像 onMounted() 这样的生命周期钩子中调用它们。

这些限制很重要,因为这些是 Vue 用于确定当前活跃的组件实例的上下文。访问活跃的组件实例很有必要,这样才能:

  1. 将生命周期钩子注册到该组件实例上
  2. 将计算属性和监听器注册到该组件实例上,以便在该组件被卸载时停止监听,避免内存泄漏。

TIP

<script setup> 是唯一在调用 await 之后仍可调用组合式函数的地方。编译器会在异步操作之后自动为你恢复当前的组件实例。