我正在使用 Vue 构建一家鞋店,问题是当我尝试通过 ShoeDetail 组件上的计算属性访问 getter 时,重新加载页面时未定义。我正在存储一些硬编码的对象数据数组在vuex状态下。在 Shoe 组件中,我使用 v-for 循环数据并在 Men View 中输出,这对我有用,显示所有可用的鞋子。当用户点击鞋子图像时,每只鞋子都会加载一条新路线,其中包含所点击鞋子的更多详细信息。我使用 id 进行动态路由。现在我在 vuex 中有一个 getter
getProductById: (state) => (id) => {
return state.sneakers.find((sneaker) => sneaker.productId === id);
},
然后我通过计算属性访问它:
product() {
return this.$store.getters.getProductById(this.$route.params.id);
},
工作正常,我可以通过 interpolitaion 输出存储在 vuex 状态的数据,如下所示:
{{product.brand}}
当我重新加载页面时,出现此错误:
**[Vue warn]: Error in render: "TypeError: Cannot read property 'brand' of undefined"
found in
---> <Detail> at src/components/ShoeDetail.vue
<App> at src/App.vue
<Root>**
我尝试使用 v-if="product"
但由于我没有进行 API 调用,因此这应该不相关。
我还安装了 createPersistedState 但它仍然不起作用。我真的被困在这里,并且提示为什么我在页面重新加载时未定义将不胜感激
我的vuex:
<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code> import Vue from 'vue';
import Vuex from 'vuex';
import createPersistedState from 'vuex-persistedstate';
Vue.use(Vuex);
export default new Vuex.Store({
plugins: [
createPersistedState({
key: 'keyname',
storage: window.localStorage,
}),
],
state: {
sneakers: [
{
productId: 1,
productno: 1234,
brand: 'nike',
gender: 'men',
size: 5,
price: 150,
image: require('@/assets/images/nike-air-zoom.jpg'),
},
{
productId: 2,
productno: 1235,
brand: 'adidas',
gender: 'men',
size: 10,
price: 140,
image: require('@/assets/images/sneakers.jpg'),
},
{
productId: 3,
productno: 1236,
brand: 'adidas',
gender: 'men',
size: 10,
price: 130,
image: require('@/assets/images/man-holding-nikes.jpg'),
},
{
productId: 4,
productno: 1237,
brand: 'nike',
gender: 'men',
size: 5,
price: 120,
image: require('@/assets/images/nike-air-zoom.jpg'),
},
{
productId: 5,
productno: 1238,
brand: 'adidas',
gender: 'men',
size: 10,
price: 110,
image: require('@/assets/images/sneakers.jpg'),
},
{
productId: 6,
productno: 1239,
brand: 'adidas',
size: 10,
price: 100,
image: require('@/assets/images/man-holding-nikes.jpg'),
},
],
},
getters: {
getProducts: (state) => {
return state.sneakers;
},
getProductById: (state) => (id) => {
return state.sneakers.find((sneaker) => sneaker.productId === id);
},
},
});</code></pre>
</div>
</div>
鞋子组件:
<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code> <template>
<div class="shoe-container">
<div class="shoe-card" v-for="element in products" :key="element.id">
<router-link
:to="{ name: 'ShoeDetail', params: { id: element.productId } }"
><img :src="element.image" tag="img" alt="" class="shoe-card__image"
/></router-link>
<p class="shoe-card__model">{{ element.brand }}</p>
<p class="shoe-card__price">{{ element.price }} $</p>
</div>
</div>
</template>
<script>
export default {
computed: {
products() {
return this.$store.getters.getProducts;
},
product() {
return this.$store.getters.getProductById(this.$route.params.id);
},
},
};
</script>
<style lang="scss" scoped>
@import '../sass/components/shoe';
</style></code></pre>
</div>
</div>
男人的观点:
<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code> <template>
<div>
<navbar></navbar>
<sub-nav></sub-nav>
<filter-section></filter-section>
<section class="shoes">
<shoe></shoe>
</section>
</div>
</template>
<script>
import Navbar from "../components/Navbar.vue";
import SubNav from "../components/SubNav.vue";
import FilterSection from "../components/FilterSection.vue";
import Shoe from "../components/Shoe.vue";
export default {
components: {
Navbar,
SubNav,
FilterSection,
Shoe
}
};
</script>
<style lang="scss" scoped>
@import "../sass/views/men";
</style></code></pre>
</div>
</div>
ShoeDetail 组件:
<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code> <template>
<div class="details">
<h1>This is details</h1>
<h2>{{ product.brand }}</h2>
</div>
</template>
<script>
export default {
name: 'detail',
computed: {
product() {
return this.$store.getters.getProductById(this.$route.params.id);
},
},
};
</script>
<style lang="scss" scoped>
@import '../sass/components/shoeDetail';
</style></code></pre>
</div>
</div>
最佳答案
感谢您的回答,我可以通过在 ShoeDetail 的计算属性中添加 parseInt 来修复它。
computed: {
product() {
return this.$store.getters.getProductById(
parseInt(this.$route.params.id)
);
},
}
关于javascript - Vue.js(vuex)。重新加载页面时,计算属性返回未定义。 (vuex 中硬编码的对象数据数组),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61479292/