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 仅供参考。
我有一个 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 仅供参考。