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

Vue页面中如何从添加组件触发列表组件刷新?可借助VueUse?

解决方案:Foo添加条目后触发Bar刷新列表

针对你这个场景,有几种可行的实现方案,包括常规Vue组件通信方式,以及用VueUse简化开发的方法,下面逐一说明:


一、常规Vue组件通信方案(父组件中转)

因为Foo和Bar都挂载在index.vue下,最直接的方式是通过父组件作为中间层传递刷新信号:

1. 修改Foo组件:添加成功后触发事件

<template>
  <h1>ADD NEW ITEM</h1>
  <v-text-field
    v-model="name"
    label="Name"
    type="text"
    @click:append="add"
  ></v-text-field>
</template>

<script setup>
import { ref } from 'vue'
// 定义要触发的事件
const emit = defineEmits(['itemAdded'])
const name = ref('')

async function add() {
  const res = await useFetch(
    "http://api.test/add",
    {
      method: "POST",
      query: {
        name: name.value, // 注意取ref的value值
      },
    }
  )
  // 确认请求成功后通知父组件
  if (res.status.value === 'success') {
    emit('itemAdded')
    name.value = '' // 清空输入框
  }
}
</script>

2. 修改Bar组件:封装刷新方法并暴露给父组件

<template>
  <h1>LIST</h1>
  <v-data-table
    v-if="mydata"
    :headers="headers"
    :items="mydata.data"
  >
  </v-data-table>
</template>

<script setup>
import { reactive } from 'vue'
// 解构出useFetch的refetch刷新方法
const { data: mydata, refetch } = await useFetch(
  "http://api.test/list",
  {
    transform(data) {
      return JSON.parse(data);
    },
    pick: ["data"],
  }
)

// 把刷新方法暴露给父组件调用
defineExpose({
  refreshList: refetch
})

const headers = reactive([
  { title: "ID", key: "id" },
  { title: "Nom", key: "name" },
  { title: "Création", key: "created_at" }
])
</script>

3. 修改index.vue:监听Foo事件,调用Bar的刷新方法

<template>
  <Foo @item-added="handleItemAdded" />
  <Bar ref="barRef" />
</template>

<script setup>
import { ref } from 'vue'
const barRef = ref(null)

const handleItemAdded = () => {
  // 调用Bar组件暴露的刷新方法
  barRef.value?.refreshList()
}
</script>

二、用VueUse实现(推荐)

VueUse提供了专门的工具可以简化组件间通信和状态监听,这里推荐两种方式:

方法1:使用useEventBus(事件总线)

useEventBus可以创建全局事件总线,跳过父组件直接在Foo和Bar之间传递信号:

1. 创建全局事件总线实例

新建utils/eventBus.js文件:

import { useEventBus } from '@vueuse/core'
// 创建名为itemAdded的事件总线
export const itemAddedBus = useEventBus('itemAdded')

2. 修改Foo组件:发布事件

<template>
  <h1>ADD NEW ITEM</h1>
  <v-text-field
    v-model="name"
    label="Name"
    type="text"
    @click:append="add"
  ></v-text-field>
</template>

<script setup>
import { ref } from 'vue'
import { itemAddedBus } from '../utils/eventBus'

const name = ref('')

async function add() {
  const res = await useFetch(
    "http://api.test/add",
    {
      method: "POST",
      query: {
        name: name.value,
      },
    }
  )
  if (res.status.value === 'success') {
    // 发布刷新事件
    itemAddedBus.emit()
    name.value = ''
  }
}
</script>

3. 修改Bar组件:订阅事件触发刷新

<template>
  <h1>LIST</h1>
  <v-data-table
    v-if="mydata"
    :headers="headers"
    :items="mydata.data"
  >
  </v-data-table>
</template>

<script setup>
import { reactive, onMounted, onUnmounted } from 'vue'
import { itemAddedBus } from '../utils/eventBus'

const { data: mydata, refetch } = await useFetch(
  "http://api.test/list",
  {
    transform(data) {
      return JSON.parse(data);
    },
    pick: ["data"],
  }
)

// 订阅事件,组件挂载时监听
onMounted(() => {
  const unsubscribe = itemAddedBus.on(() => {
    refetch()
  })
  // 组件销毁时取消订阅,避免内存泄漏
  onUnmounted(unsubscribe)
})

const headers = reactive([
  { title: "ID", key: "id" },
  { title: "Nom", key: "name" },
  { title: "Création", key: "created_at" }
])
</script>

方法2:使用useSignal(信号量监听)

用useSignal创建一个全局信号量,Foo修改信号量状态,Bar监听状态变化触发刷新:

1. 创建全局信号量

新建utils/signals.js文件:

import { useSignal } from '@vueuse/core'
// 创建用于触发列表刷新的信号量
export const refreshListSignal = useSignal(false)

2. Foo组件:修改信号量状态

// 在add函数成功后添加
refreshListSignal.value = !refreshListSignal.value

3. Bar组件:监听信号量变化

import { watch } from 'vue'
import { refreshListSignal } from '../utils/signals'

// 监听信号量变化,触发刷新
watch(refreshListSignal, () => {
  refetch()
})

三、注意事项

  • 必须确保API请求确实成功后再触发刷新,避免无效操作
  • 使用事件总线或信号量时,记得在组件销毁时取消监听,防止内存泄漏
  • 使用VueUse前需先安装:npm i @vueuse/core

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 03:33:15