Vue3如何让自定义Hook响应式?传入Ref未触发更新问题
解决自定义Hook的响应式问题
你的问题出在:当前的useOpeningHours只会在第一次调用时执行一次逻辑,返回固定的对象,没有对flight的变化建立响应式依赖,所以当flight的值更新时,Hook不会重新计算返回结果。
下面给两种可行的修复方案:
方案一:使用computed推导响应式结果
利用computed自动追踪依赖的特性,把返回值的逻辑放在computed内部,这样当flight变化时,结果会自动更新:
export const useOpeningHours = ( flight: Ref<FlightOption | null>, identifier: string, isEnabled?: boolean ) => { return computed(() => { if (!flight.value || !isEnabled) { return { show: false, gate: "", }; } // 这里补充你原本的业务逻辑,比如根据flight和identifier处理gate等 return { show: true, gate: flight.value.gate // 示例,按需修改 }; }); };
调用时如果需要解构,可以配合toRefs(因为computed返回的是只读响应式对象):
const flight = ref<FlightOption | null>(null); const openingHours = useOpeningHours(flight, props.identifier, true); const { show: showOpeningHours, gate } = toRefs(openingHours);
方案二:使用watch监听变化并维护内部状态
如果你的逻辑更复杂,适合用watch监听flight的变化,手动更新内部的响应式状态:
import { ref, watch, isRef } from 'vue'; export const useOpeningHours = ( flight: Ref<FlightOption | null>, identifier: string, isEnabled?: boolean ) => { const show = ref(false); const gate = ref(""); // 定义更新逻辑的函数 const updateState = () => { if (!flight.value || !isEnabled) { show.value = false; gate.value = ""; return; } // 补充业务逻辑 show.value = true; gate.value = flight.value.gate; }; // 初始化时执行一次 updateState(); // 监听flight变化,自动更新状态 watch(flight, updateState, { deep: true }); // 如果FlightOption是复杂对象,需要开启deep监听 // 若isEnabled是响应式的,也可以监听它的变化 if (isEnabled !== undefined && isRef(isEnabled)) { watch(isEnabled, updateState); } return { show, gate }; };
调用时直接解构即可,因为返回的是ref对象:
const flight = ref<FlightOption | null>(null); const { show: showOpeningHours, gate } = useOpeningHours(flight, props.identifier, true);
另外要注意:如果identifier是响应式值(比如来自props的响应式属性),记得把它也加入依赖——方案一中在computed里用到identifier即可自动追踪,方案二中则需要把identifier加入watch的监听列表。
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

