La page dynamique Nuxt 3 change d'URL mais le contenu reste le même et les données ne sont récupérées qu'une seule fois
P粉476883986
P粉476883986 2023-11-03 14:39:04
0
1
714

J'ai un products/index 页面,主产品页面中有 products/[slug] 我有一个 NuxtLink 来更改页面并转到 products/[slug] et j'obtiens des données pour ce produit.

Au premier clic, j'ai les données correctes, mais lorsque je clique en arrière ou que je clique sur la page produit/index et que j'essaie ensuite de cliquer sur un autre produit, j'ai le premier produit sur lequel j'ai cliqué et les informations pour chaque produit et j'obtiens encore une fois J'ai obtenu des informations sur le premier produit sur lequel j'ai cliqué.

L'utilisation de console.log m'a permis de découvrir que mes données de récupération n'ont pas changé, est-ce que j'ai raté quelque chose ici ?

ne fonctionne pas dans 上使用 :key:page-key.

Le premier produit sur lequel j'ai cliqué

Le deuxième produit n'a toujours aucun changement, les données proviennent du premier produit

La troisième photo est toujours inchangée

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.vuePage

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

产品/[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>


P粉476883986
P粉476883986

répondre à tous(1)
P粉759457420

J'ai trouvé la solution Je dois ajouter un paramètre dans useFetch

const {data: productData, pending, refresh, error} = await useFetch(`http://127.0.0.1:8000/api/products/${slug}` , { initialCache: false })

Parce que l'API se met en cache et n'enverra pas d'autre requête, utilisez initialCache : false il enverra une autre demande Cette méthode fonctionne très bien pour le produit principal, mais dans les produits/[slug] ou le blog/[slug], je pense que vous devez le faire, si vous avez une meilleure méthode, laissez-moi un commentaire

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal