如何在不使用监听器时,通过组合式函数触发调用Setup内的函数
解决方案
方案1:让组合式函数支持回调触发
如果可以修改组合式函数的代码,最直接的方式是给它加一个回调注册机制,当markedAsStarred变化时主动调用组件里的刷新函数:
- 修改组合式函数,添加回调注册和触发逻辑:
// 组合式函数文件(比如useStarred.ts) import { ref } from 'vue' export function useStarred() { const markedAsStarred = ref(false) let starChangeCallback: (() => void) | undefined // 这里是组合式函数内部修改markedAsStarred的逻辑(比如处理事件的函数) function handleStarTrigger() { markedAsStarred.value = !markedAsStarred.value // 触发组件传入的回调 starChangeCallback?.() } // 提供给组件注册回调的方法 function registerStarChangeCallback(callback: () => void) { starChangeCallback = callback } return { markedAsStarred, handleStarTrigger, registerStarChangeCallback } }
- 在组件中注册刷新函数作为回调:
<script setup lang="ts"> import { useStarred } from './useStarred' import { ref } from 'vue' const { markedAsStarred, registerStarChangeCallback } = useStarred() let starredList = ref<any[]>() async function refreshStarredList() { // 这里写发起HTTP请求并更新starredList的逻辑 starredList.value = await fetch('/api/starred-items').then(res => res.json()) } // 注册回调,markedAsStarred变化时自动执行刷新 registerStarChangeCallback(refreshStarredList) </script> <template> <childComponent :starredList="starredList" /> </template>
方案2:将刷新逻辑内聚到组合式函数中
把列表刷新和响应式变量的监听都放到组合式函数内部,组件直接使用返回的结果即可,无需自己处理监听逻辑:
// 组合式函数文件 import { ref, watch } from 'vue' export function useStarredList() { const markedAsStarred = ref(false) const starredList = ref<any[]>() async function refreshStarredList() { // 实际HTTP请求逻辑 starredList.value = await fetch('/api/starred-items').then(res => res.json()) } // 组合式函数内部监听markedAsStarred,组件无需关心 watch(markedAsStarred, () => { refreshStarredList() }, { immediate: true }) // immediate: true 确保初始化时也执行一次刷新 return { markedAsStarred, starredList } }
组件中直接使用:
<script setup lang="ts"> import { useStarredList } from './useStarredList' const { starredList } = useStarredList() </script> <template> <childComponent :starredList="starredList" /> </template>
方案3:利用响应式依赖自动追踪(无需显式watch)
如果不想修改组合式函数,可以用watchEffect(它会自动追踪响应式依赖,不属于传统显式watch写法),当markedAsStarred变化时自动触发刷新:
<script setup lang="ts"> import { markedAsStarred } from '....' import { ref, watchEffect } from 'vue' let starredList = ref<any[]>() async function refreshStarredList() { // HTTP请求更新列表逻辑 starredList.value = await fetch('/api/starred-items').then(res => res.json()) } // 自动追踪markedAsStarred的变化,触发刷新 watchEffect(() => { // 访问markedAsStarred建立响应式依赖 markedAsStarred.value refreshStarredList() }) </script>
内容的提问来源于stack exchange,提问作者tsiPlus
相关产品推荐
相关产品推荐

