Vue3如何使这个钩子具有响应性?

huangapple go评论68阅读模式
英文:

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&lt;FlightOption | null&gt;,
  identifier: string,
  isEnabled?: boolean
) =&gt; {
  if (!flight.value) {
    return {
      show: false,
      gate: &quot;&quot;,
    };
  }
}

const flight = ref&lt;FlightOption | null&gt;(null);

const { show: showOpeningHours } = useOpeningHours(
  flight,
  props.identifier,
  true
);

I would expect because I use Ref&lt;FlightOption | null&gt; 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(() => {...}),
    }
}

这里返回的 showgateComputedRef,与 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&lt;FlightOption | null&gt;,
  identifier: string,
  isEnabled?: boolean
) =&gt; {
    return {
      show: computed(() =&gt; {
        if (flight.value) return false
        return true
      }),
      gate: computed(() =&gt; {...}),
    }
}

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&lt;FlightOption | null&gt;,
  identifier: string,
  isEnabled?: boolean
) =&gt; {
  return toReactive(computed(() =&gt; {
    if (!flight.value) {
      return {
        show: false,
        gate: &quot;&quot;,
      };
    }

    return {
      show: ...,
      gate: ...
    } 
  }))
}


const flight = ref&lt;FlightOption | null&gt;(null);

const { show: showOpeningHours } = toRefs(useOpeningHours(
  flight,
  props.identifier,
  true
));

use Reactive

export const useOpeningHours = (
  flight: Ref&lt;FlightOption | null&gt;,
  identifier: string,
  isEnabled?: boolean
) =&gt; {
  const result = reactive({ &lt;default value&gt; })

  watchEffect(() =&gt; { // or watch, watchPostEffect, watchSyncEffect
    if (!flight.value) {
      result.show = false
      result.gate = &quot;&quot;
    }
    ...
  })

  return result
}


const flight = ref&lt;FlightOption | null&gt;(null);

const { show: showOpeningHours } = toRefs(useOpeningHours(
  flight,
  props.identifier,
  true
));

use Ref

export const useOpeningHours = (
  flight: Ref&lt;FlightOption | null&gt;,
  identifier: string,
  isEnabled?: boolean
) =&gt; {
  const show = ref(false)
  const gate = ref(&quot;&quot;)

  watch(flight, flight =&gt; { // or watchEffect
    if (!flight) {
      show.value = false
      gate.value = &quot;&quot;
    }

    ...
  }, { 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&lt;FlightOption | null&gt;, identifier: string, isEnabled?: boolean) =&gt; {
  const details = computed(() =&gt; {
    if (!flight.value) {
      return {
        show: false,
        gate: &quot;&quot;,
      };
    } else {
      return {
        show: true,
        gate: &quot;GATE 1&quot;,
      };
    }
  });

    return {
        details
    };
};

and use it like :

const { details } = toRefs(useOpeningHours(
  flight,
  props.identifier,
  true
));

//then use `details.value.show` or `details.value.gate`

huangapple
  • 本文由 发表于 2023年3月9日 18:15:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75683189.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定