【问题标题】:Nuxt Composition API, updating 'state', not reflected on UI TemplateNuxt Composition API,更新“状态”,未反映在 UI 模板上
【发布时间】:2021-11-25 05:57:37
【问题描述】:

我有一个使用选项 API 的 Nuxt.js 应用程序。随着新 Nuxt3 的问世,我试图将事物迁移到所谓的“更好”的替代方案。到目前为止,我只有挑战,也许那是我缺乏知识。

我正在构建一个包含以下组件的基本电子商务平台

# 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>

我需要注意的一点是,如果产品获得评论/评级,我希望 UI 更新为产品星级,因此需要更多的反应性。

我继续获得undefined 产品变量

在我的 VueX 商店里,我有我的吸气剂

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

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

【问题讨论】:

    标签: javascript nuxt.js vuex vue-composition-api


    【解决方案1】:

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

    所以,你从你的设置函数返回的是

    product: computed(() =&gt; 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 FYI。

    【讨论】:

    • 谢谢普拉尚特!你能解释为什么你不只设置 const 产品,而不是使用 alreadyExistingProduct 吗?设置一次,然后让它在那个时候反应?
    猜你喜欢
    • 1970-01-01
    • 2021-03-26
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多