You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue 3组合式函数间如何通信?求最佳实现方案

Vue组合式函数间通信的最佳实践

问题背景

在Vue应用中,使用useUsers和useStatistics两个组合式函数时,需要在useStatistics的loadStatistics方法中修改useUsers内部的selectedUser ref变量,但由于作用域限制无法直接访问,以下是几种最佳实践方案。


方案1:直接传入目标Ref变量

将需要修改的selectedUser ref作为参数传递给useStatistics,让其内部方法直接操作ref的value属性,这是最直接的方式。

修改后的代码:

ShowStatistics.vue

<template>
  <select v-model="selectedUser">
    <option v-for="user in users" :key="user.id" :value="user">
      {{ user.name }}
    </option>
  </select>

  <button @click="loadStatistics">
    Load Statistics
  </button>
</template>

<script setup lang="ts">
import { useUsers, useStatistics } from './composables'
const { users, selectedUser } = useUsers()
// 把selectedUser传入useStatistics
const { loadStatistics } = useStatistics(selectedUser)
</script>

useStatistics.ts

import type { Ref } from 'vue'

export function useStatistics(selectedUser: Ref<any>) {
  const loadStatistics = () => {
    const statistics = StatisticsApi.loadStatistics()
    window.store.statistics = statistics
    // 直接修改ref的value
    selectedUser.value = statistics.user
  }

  return { loadStatistics }
}

方案2:封装修改方法到源组合式函数

在useUsers内部封装修改selectedUser的方法,只暴露方法给外部调用,保持数据的封装性,避免外部直接操作内部状态,符合单一职责原则。

修改后的代码:

useUsers.ts

import { ref } from 'vue'

export function useUsers() {
  const users = ref([])
  const selectedUser = ref({})

  users.value = UsersApi.getUsers()

  // 封装修改选中用户的方法
  const setSelectedUser = (user: any) => {
    selectedUser.value = user
  }

  return { users, selectedUser, setSelectedUser }
}

ShowStatistics.vue

<template>
  <select v-model="selectedUser">
    <option v-for="user in users" :key="user.id" :value="user">
      {{ user.name }}
    </option>
  </select>

  <button @click="loadStatistics">
    Load Statistics
  </button>
</template>

<script setup lang="ts">
import { useUsers, useStatistics } from './composables'
const { users, selectedUser, setSelectedUser } = useUsers()
// 传入修改方法到useStatistics
const { loadStatistics } = useStatistics(setSelectedUser)
</script>

useStatistics.ts

export function useStatistics(setSelectedUser: (user: any) => void) {
  const loadStatistics = () => {
    const statistics = StatisticsApi.loadStatistics()
    window.store.statistics = statistics
    // 调用传入的方法修改选中用户
    setSelectedUser(statistics.user)
  }

  return { loadStatistics }
}

方案3:使用全局状态管理(如Pinia)

如果selectedUser是多个组件或组合式函数需要共享的状态,推荐使用全局状态管理工具(如Pinia),将状态抽离到全局store中,所有相关逻辑都通过store操作状态。

修改后的代码:

stores/userStore.ts

import { defineStore } from 'pinia'
import { ref } from 'vue'

export const useUserStore = defineStore('user', () => {
  const users = ref([])
  const selectedUser = ref({})

  // 获取用户列表的方法
  const fetchUsers = () => {
    users.value = UsersApi.getUsers()
  }

  // 修改选中用户的方法
  const setSelectedUser = (user: any) => {
    selectedUser.value = user
  }

  return { users, selectedUser, fetchUsers, setSelectedUser }
})

useUsers.ts

import { useUserStore } from '../stores/userStore'

export function useUsers() {
  const userStore = useUserStore()
  // 初始化用户数据
  userStore.fetchUsers()

  return {
    users: userStore.users,
    selectedUser: userStore.selectedUser,
    setSelectedUser: userStore.setSelectedUser
  }
}

useStatistics.ts

import { useUserStore } from '../stores/userStore'

export function useStatistics() {
  const userStore = useUserStore()

  const loadStatistics = () => {
    const statistics = StatisticsApi.loadStatistics()
    window.store.statistics = statistics
    // 通过store修改选中用户
    userStore.setSelectedUser(statistics.user)
  }

  return { loadStatistics }
}

内容的提问来源于stack exchange,提问作者Martin Zeltin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 11:48:23