I have a products/index
page with products/[slug]
in the main product page and I have a NuxtLink
to change the page and go to products/[slug]
and get the data for that product.
On the first click, I have the correct data, but when I click back or click on the product/index page and then try to click on another product, I have the first product I clicked on and the information for each product, Again I got the information for the first product I clicked on.
Using console.log
allowed me to find that my fetched data has not changed, am I missing something here?
Using :key
on does not work.
The first product I clicked
The second product is still unchanged, the data comes from the first product
The third picture is still unchanged
productComponent.vue
<template> <div class="mx-auto rounded border mb-7 border-blue-200 pt-1 px-2 mx-1 mb-2"> <NuxtLink :to="link"> <img class="rounded mx-auto mb-3 border-b border-y-blue-300 pb-3" :src="img" :alt="alt" /> <div class="mt-2"> <div> <div class="items-center font-bold text-slate-700 leading-snug"> <p class="pr-3">{{ title }}</p> </div> <div class="mt-2 text-lg text-slate-600 pr-3 pb-2"> قیمت : {{ price }} تومان </div> </div> </div> </NuxtLink> </div> </template> <script> export default { name: 'ProductComponent', props: ['title', 'price', 'img', 'alt', 'link'], } </script>
products/index.vue
Page
<script setup> useHead({ title: 'محصولات', }) const {data, pending, refresh, error} = await useFetch('http://127.0.0.1:8000/api/products') const products=data._value.data.data </script> <template> <div> <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div class="relative z-10 flex items-baseline justify-between pt-24 pb-6 border-b mb-7 border-gray-200"> <h1 class="text-4xl font-extrabold tracking-tight ">محصولات</h1> </div> <div class=" border border-blue-300 mx-auto p-4 mb-7"> <div class="grid sm:grid-cols-2 md:grid-cols-2 gap-2 lg:grid-cols-3 xl:grid-cols-4"> <div v-for="(product,index) in products" :key="index"> <product-component :title="product.name" :price="product.price" :img="'http://127.0.0.1:8000/'+product.image[0].indexArray.large" :alt="product.name" :link="'/products/'+product.slug"> </product-component> </div> </div> </div> </main> </div> </template>
product/[slug]
<script setup> const route = useRoute(); const {data: productData, pending, refresh, error} = await useFetch(`http://127.0.0.1:8000/api/products/${route.params.slug}`) const product = productData._value.data[0] console.log(product) </script> <template> <div class="container mx-auto"> <section class="grid grid-cols-12 gap-3 mb-7 "> <!-- little pic--> <div class="md:col-span-1 mx-auto md:flex md:flex-wrap hidden overflow-auto" style="max-height: 36rem"> <div class="cursor-pointer bg-amber-100 max-h-9"> <div class="max-h-fit mb-3 " v-for="(myImage , index) in product.image" :key="index" @click="switchImage('http://127.0.0.1:8000/'+myImage.indexArray.large)"> <img class="object-fill " style="width: 80px;height: 60px" :src="'http://127.0.0.1:8000/'+myImage.indexArray.large" :alt="myImage.alt"> </div> </div> </div> <!-- end of little pic--> <!-- pic--> <div v-if="image" class="md:col-span-6 col-span-12 w-100 w-full max-w-full"> <img class="" :src="image" :alt="image.alt"> </div> <div v-else class="md:col-span-6 col-span-12 "> <img class="object-fill" :src="'http://127.0.0.1:8000/'+product.image[0].indexArray.large" alt=""> </div> <!--end of pic--> <div class="col-span-12 md:hidden"> <div class="cursor-pointer overflow-x-scroll"> <div class=" mb-3 inline py-1 " v-for="(myImage , index) in product.image" :key="index" @click="switchImage(index)"> <img class="object-fill inline p-1 overflow-x-scroll" style="width: 80px;height: 60px" :src="myImage.url" :alt="myImage.alt"> </div> </div> </div> <!-- details--> <div class="col-span-12 md:col-span-4"> <div class="flex justify-between border-b border-amber-200 p-1 mb-4"> <p> نام محصول :</p> <p>{{ product.name }}</p> </div> <div class="flex justify-between border-b border-amber-200 p-1 mb-4"> <p> کشور :</p> <p>{{ product.country }}</p> </div> <div class="flex justify-between border-b border-amber-200 p-1 mb-4"> <p> جنس :</p> <p>{{ product.material }}</p> </div> <div class="flex justify-between border-b border-amber-200 p-1 mb-4"> <p> سن :</p> <p>{{ product.age }}</p> </div> <div class="flex justify-between border-b border-amber-200 p-1 mb-4"> <p> رنگ :</p> <p>{{ product.color }}</p> </div> <div class="flex justify-between border-b border-amber-200 p-1 mb-4"> <p> وزن :</p> <p>{{ product.weight }}</p> </div> <div class="flex justify-between border-b border-amber-200 p-1 mb-4"> <p> طول :</p> <p>{{ product.length }}</p> </div> <div class="flex justify-between border-b border-amber-200 p-1 mb-4"> <p> عرض :</p> <p>{{ product.width }}</p> </div> <div class="flex justify-between border-b border-amber-200 p-1 mb-4"> <p> ارتفاع :</p> <p>{{ product.height }}</p> </div> <div class="flex justify-between border-b border-amber-200 p-1 mb-4"> <p> قیمت :</p> <p>{{ product.price }}</p> </div> </div> <!-- end of details--> </section> <div class="p-3 mb-7" style="background-color:beige;"> <ul class="flex flex-row md:space-x-6"> <li class="block py-2 pr-4 pl-3 text-black"> توضیحات </li> </ul> </div> <div class="mb-5 mx-auto whitespace-normal p-1 border-b border-amber-100-200 "> <div v-html="product.description"></div> </div> <div class="mb-7"> <span class="block mb-4"> برچسب ها : </span> <a v-for="(tags , index) in product.tags.split(',')" :title="tags" :key="index" class="rounded-md text-sm" style="margin: 3px" rel="tag" href="">{{ tags }} / </a> </div> </div> </template> <script> export default { data() { return { image: null, } }, methods: { switchImage(index) { this.image = index; }, }, } </script>
I found the solution I have to add a parameter
in useFetchBecause the api caches and will not send another request, use
initialCache : false
it will send another request This way works fine for main product, but in products/[slug] or blog/[slug] I think you have to do this, if you have a better way please leave me a comment