英文:
Vue3 how do I make this hook reactive
问题
export const useOpeningHours = (
flight: Ref<FlightOption | null>,
identifier: string,
isEnabled?: boolean
) => {
if (!flight.value) {
return {
show: false,
gate: "",
};
}
}
const flight = ref<FlightOption | null>(null);
const { show: showOpeningHours } = useOpeningHours(
flight,
props.identifier,
true
);
英文:
I've got a hook that looks like this (simplified this example):
export const useOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
  if (!flight.value) {
    return {
      show: false,
      gate: "",
    };
  }
}
const flight = ref<FlightOption | null>(null);
const { show: showOpeningHours } = useOpeningHours(
  flight,
  props.identifier,
  true
);
I would expect because I use Ref<FlightOption | null> the hook would be 'refreshed' when the flight changes. However, that is not happening. How can I make sure the hook is reactive with this example?
答案1
得分: 4
以下是代码部分的翻译:
使用 ComputedRef
更多信息:https://vuejs.org/guide/essentials/computed.html#basic-example
export const useOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
    return {
      show: computed(() => {
        if (flight.value) return false
        return true
      }),
      gate: computed(() => {...}),
    }
}
这里返回的 show 和 gate 是 ComputedRef,与 show.value 相同。
如果使用 @vueuse/core,有更简便的方法:
export const useOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
  return toReactive(computed(() => {
    if (!flight.value) {
      return {
        show: false,
        gate: "",
      };
    }
    return {
      show: ...,
      gate: ...
    } 
  }))
}
const flight = ref<FlightOption | null>(null);
const { show: showOpeningHours } = toRefs(useOpeningHours(
  flight,
  props.identifier,
  true
));
使用 Reactive
export const useOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
  const result = reactive({ <默认值> })
  watchEffect(() => { // 或 watch, watchPostEffect, watchSyncEffect
    if (!flight.value) {
      result.show = false
      result.gate = ""
    }
    ...
  })
  return result
}
const flight = ref<FlightOption | null>(null);
const { show: showOpeningHours } = toRefs(useOpeningHours(
  flight,
  props.identifier,
  true
));
使用 Ref
export const useOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
  const show = ref(false)
  const gate = ref("")
  watch(flight, flight => { // 或 watchEffect
    if (!flight) {
      show.value = false
      gate.value = ""
    }
    ...
  }, { immediate: true })
  return { show, gate }
}
英文:
Since you said this is simplified i will treat it as a complicated thing you have 3 methods
Use ComputedRef
More info: https://vuejs.org/guide/essentials/computed.html#basic-example
export const useOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
    return {
      show: computed(() => {
        if (flight.value) return false
        return true
      }),
      gate: computed(() => {...}),
    }
}
This returns show and gate is a ComputerRef it's the same as show.value
If you use @vueuse/core you have an easier way
export const useOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
  return toReactive(computed(() => {
    if (!flight.value) {
      return {
        show: false,
        gate: "",
      };
    }
    return {
      show: ...,
      gate: ...
    } 
  }))
}
const flight = ref<FlightOption | null>(null);
const { show: showOpeningHours } = toRefs(useOpeningHours(
  flight,
  props.identifier,
  true
));
use Reactive
export const useOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
  const result = reactive({ <default value> })
  watchEffect(() => { // or watch, watchPostEffect, watchSyncEffect
    if (!flight.value) {
      result.show = false
      result.gate = ""
    }
    ...
  })
  return result
}
const flight = ref<FlightOption | null>(null);
const { show: showOpeningHours } = toRefs(useOpeningHours(
  flight,
  props.identifier,
  true
));
use Ref
export const useOpeningHours = (
  flight: Ref<FlightOption | null>,
  identifier: string,
  isEnabled?: boolean
) => {
  const show = ref(false)
  const gate = ref("")
  watch(flight, flight => { // or watchEffect
    if (!flight) {
      show.value = false
      gate.value = ""
    }
    ...
  }, { immediate: true })
  return { show, gate }
}
答案2
得分: 0
尝试如下使用计算属性:
export const useOpeningHours = (flight: Ref<FlightOption | null>, identifier: string, isEnabled?: boolean) => {
  const details = computed(() => {
    if (!flight.value) {
      return {
        show: false,
        gate: "",
      };
    } else {
      return {
        show: true,
        gate: "GATE 1",
      };
    }
  });
  return {
    details
  };
};
然后像这样使用它:
const { details } = toRefs(useOpeningHours(
  flight,
  props.identifier,
  true
));
// 然后使用 `details.value.show` 或 `details.value.gate`
英文:
Try to use a computed property as follows :
export const useOpeningHours = (flight: Ref<FlightOption | null>, identifier: string, isEnabled?: boolean) => {
  const details = computed(() => {
    if (!flight.value) {
      return {
        show: false,
        gate: "",
      };
    } else {
      return {
        show: true,
        gate: "GATE 1",
      };
    }
  });
    return {
        details
    };
};
and use it like :
const { details } = toRefs(useOpeningHours(
  flight,
  props.identifier,
  true
));
//then use `details.value.show` or `details.value.gate`
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论