Nuxt Composition API,正在更新 'state',未反映在 UI 模板上

Nuxt Composition API, updating 'state', not reflected on UI Template

我有一个 Nuxt.js 应用程序使用选项 API。随着新的 Nuxt3 的出现,我试图将事情迁移到所谓的 'better' 替代方案。到目前为止,我除了挑战什么都没有,也许那是我缺乏知识。

我正在构建一个基本的电子商务平台,其组件为

# products/_id.vue
<template>
  <div>
    {{ product }}
  </div>
</template>
<script>
import {
  defineComponent,
  useFetch,
  useStore,
  useRoute,
  ssrRef, reactive, watch
} from '@nuxtjs/composition-api'

export default defineComponent({
  setup () {
    const store = useStore()
    const route = useRoute()
    const loading = ref(false)

    // LOAD PRODUCT FROM VUEX STORE IF ALREADY LOADED
    const product = reactive(store.getters['products/loaded'](route.value.params.id))

    // GET PAGE CONTENT
    const { fetch } = useFetch(async () => {
      loading.value = true
      await store.dispatch('products/getOne', route.value.params.id)
      loading.value = false
    })

    // WATCH, if a use navigates to another product, we need to watch for changes to reload
    watch(route, () => {
      if (route.value.params.id) {
        fetch()
      }
    })

    return {
      loading
      product
    }
  }
})
</script>

我需要注意的一件事是,如果产品获得 comment/rating,我希望 UI 更新产品星级,因此需要更多的反应。

我继续获得 undefined 产品变量

在我的 VueX 商店里我有我的 getters

loaded: state => (id) => {
    try {
      if (id) {
        return state.loaded[id]
      }
      return state.loaded
    } catch {
      return {}
    }
  }

寻找有关如何让它工作的指导,改进我当前设置的任何代码。

如果你想保持对你的getter的反应引用,那么你必须create a computed property

那么,您从设置函数中 return 得到的是

product: computed(() => getters['products/loaded'](route.value.params.id))

这将确保每当 getter 更新时,您的组件都会收到该更新。

此外,如果该产品已经存在,您应该放弃获取功能。这样您就不会进行额外的 API 调用。

最后,如果出现错误,您可以重定向到 404 错误页面。

总而言之,您的设置函数可能如下所示

 setup() {
  const route = useRoute();
  const { error } = useContext();
  const { getters, dispatch } = useStore();

  const loading = ref(false);

  const alreadyExistingProduct = getters['products/loaded'](route.value.params.id);

  const { fetch } = useFetch(async () => {
    // NEW: bail if we already have the product
    if (alreadyExistingProduct) return;

    try {
      loading.value = true;
      await dispatch('products/getOne', route.value.params.id);
    } catch {
      // NEW: redirect to error page if product could not be loaded
      error({ statusCode: 404 });
    } finally {
      loading.value = false;
    }
  });

  watch(route, () => {
    if (route.value.params.id) {
      fetch();
    }
  });

  return {
    loading,
    // NEW: computed property to maintain reactive reference to getter
    product: computed(() => getters['products/loaded'](route.value.params.id)),
  };
},

您可能还会 运行 进入 this harmless issue 仅供参考。