Как при нажатии на кнопки (виды товара) в карточке товара перейти на товар с выбранной кнопкой на vuejs

Рейтинг: 0Ответов: 2Опубликовано: 29.06.2023

Суть в чем: есть компонент, в котором есть кнопки вида товара, выполняющие функцию перехода на другой товар, соответствующие кнопке, пример: Карточка товара В данном случае это кнопки Putty(база), Light body (коррегирующий слой), Activator (активатор) Json-файл

Компонент:

<template>
  <Header_Product/>
  <div class="product-info" v-if="product">
    <h1 class="title">{{ product.title }}</h1>
    <div class="imgs">
      <div class="left-images">
        <a class="button-image" href="#">
          <img class="spidex_active" :src="product.img1">
        </a>
        <div class="photo">Фото товара условное</div>
        <ul class='images'>
          <img class="images_li" :src="product.imgs1">
          <img class="images_li" :src="product.imgs2">
          <img class="images_li" :src="product.imgs3">
        </ul>
      </div>
      <div class="about-product">
        <div class="body__body-image-1">
          <div class="info-price">
            <router-link to="/">
              <img class="coltene" :src="product.img2">
            </router-link>
          </div>

          <div class="like-info-1">
            <span>Фирма:</span>
            <span>{{ product.firm }}</span>
          </div>

          <div class="like-info-1">
            <span>Страна: </span>
            <span>{{ product.country }}</span>
          </div>
          <h2>Коротко о товаре</h2>
          <div class="description">
            <li>Цвет: зеленый</li>
            <li>Совместимость с материалами: слепочные массы Speedex любой консистенции.</li>
            <li>Время замешивания и дозировка: согласно инструкции к слепочной массе.</li>
            <li>Объем: 60 миллилитров.</li>
            <li>Время смешивания, рабочее время и время застывания во рту зависят от количества активатора. Минимальное - при превышении нормы на 30%.</li>
          </div>
        </div>
        <div class="body__body-image">
          <ul class='rating' v-for='i in 5'>
            <img class="rating_li" :src="product.star">
          </ul>

          <div class="info">

            <div class="in-stock-dont-stock">
              <span>{{ product.availability }}</span>
            </div>

            <h2 class="text-info">Тип:</h2>
            <div class="options">
              <button class="add-to-cart-1">
                {{ product.type }}
              </button>
            </div>

            <h2 class="text-info">Вид:</h2>
            <div class="options">
              <button class="add-to-cart-1" v-for="option of product.options" @click = "router.push(`/product/${product.id}}`)">
                  {{ option }}
              </button>
            </div>

            <div class="info-price">
              <span class="price">{{ product.price }} <small>₽</small></span>
              <div class="like-buy">
                <button class="like-info">
                  <img src="../../../public/images/like.svg" class="like" alt="like">
                </button>
                <button class="add-to-cart">
                  <img class="cart" src="../../../public/images/outline-shopping-cart.svg" alt="shop">
                  В корзину
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <v-select/>
  </div>
  <div v-else><h1>Product not founds</h1></div>
  <Footer/>
</template>

Функции:

<script setup>
import products from "@/mocks/products.json"
import Product from "@/Pages/Product.vue";
import VSelect from "@/Layout/ProductPages/v-select.vue";

import {ref, onBeforeMount} from "vue";
import {useRoute, useRouter} from "vue-router";
import Header_Product from "@/Layout/ProductPages/Header_Product.vue";
import Footer from "@/Layout/Main/Footer.vue";

const product = ref(null)
const route = useRoute()
const router = useRouter()
const {id} = route.params
onBeforeMount(() => {
  product.value = products.find(c => c.id === parseInt(id))
});

</script>

Пытался реализовать отдельным компонентом, не получается

Ответы

▲ 0Принят

Я бы сделал так:

  1. Немного доработал свойство options, сделав пары (код, текст):
"options": [
   "Putty": "база",
   "Light body": "коррегирующий слой",
   "Activator": "активатор"
]
  1. Добавил свойство option. Если товар основной, то option="", если дополнение, то заполняем соответственно, например option="Putty".

  2. Ну а дальше уже просто - проверяем option:

<button class="add-to-cart-1" v-for="(text,key) of product.options" @click = "router.push(`/product/${product.id}}`)" 
    v-bind:class="{active: key == option}">
    {{ key }} ({{text}})
</button>
▲ 0

По итогу сделал вот как (оно работает):

<button
    class="add-to-cart-1"
    v-for="(text, key) of product.options"
    @click="goToProductPage(getProductIdByOption(key))"
    :class="{ active: key === selectedOption }">
    {{ key }} ({{ text }})
</button>

Добавил функций, которые обновляют состояние страницы с выбранным id и ищут среди массива options ключ, равный значению option в json-файле:

[
  {
    "id": 1,
    "title": "Speedex Activator - Спидекс активатор, 60г, Coltene.",
    "img": "/images/spidex_active-1.jpg",
    "imgs1": "/images/spidex_active-1.jpg",
    "imgs2": "/images/spidex_active-2.jpg",
    "imgs3": "/images/spidex_active-3.jpg",
    "img2": "/images/coltene.png",
    "firm": "Coltene",
    "country": "Швейцария",
    "star": "/images/star.svg",
    "availability": "В наличии",
    "type" : "Speedex",
    "options": {
      "Putty": "база",
      "Light body": "коррегирующий слой",
      "Activator": "активатор"
    },
    "option": "Activator",
    "price": 1182
  },
  {
    "id": 2,
    "title": "Алмадез-Лайт, мыло-крем антибактериальное, дозатор-насос 1л",
    "img": "/images/1.jpg",
    "imgs1": "/images/1.jpg",
    "imgs2": "/images/1.jpg",
    "imgs3": "/images/1.jpg",
    "img2": "/images/coltene.png",
    "firm": "Coltene",
    "country": "Швейцария",
    "star": "/images/star.svg",
    "availability": "В наличии",
    "type" : "Speedex",
    "price": 1182
  },
  {
    "id": 3,
    "title": "Алмадез-экспресс 50мл",
    "img": "/images/3.jpg",
    "imgs1": "/images/3.jpg",
    "imgs2": "/images/3.jpg",
    "imgs3": "/images/3.jpg",
    "img2": "/images/coltene.png",
    "firm": "Coltene",
    "country": "Швейцария",
    "star": "/images/star.svg",
    "availability": "В наличии",
    "type" : "Speedex",
    "price": 1182
  },
  {
    "id": 4,
    "title": "Speedex light body, коррегирующий слой, 140г, Coltene",
    "img": "/images/spidex_correct-1.jpg",
    "imgs1": "/images/spidex_correct-1.jpg",
    "imgs2": "/images/spidex_correct-2.jpg",
    "imgs3": "/images/spidex_correct-3.jpg",
    "img2": "/images/coltene.png",
    "firm": "Coltene",
    "country": "Швейцария",
    "star": "/images/star.svg",
    "availability": "В наличии",
    "type" : "Speedex",
    "options": {
      "Putty": "база",
      "Light body": "коррегирующий слой",
      "Activator": "активатор"
    },
    "option": "Light body",
    "price": 1182
  },
  {
    "id": 5,
    "title": "Speedex Putty - Спидекс база (910мл), Coltene",
    "img": "/images/spidex_base-1.jpg",
    "imgs1": "/images/spidex_base-1.jpg",
    "imgs2": "/images/spidex_base-2.jpg",
    "imgs3": "/images/spidex_base-3.jpg",
    "img2": "/images/coltene.png",
    "firm": "Coltene",
    "country": "Швейцария",
    "star": "/images/star.svg",
    "availability": "В наличии",
    "type" : "Speedex",
    "options": {
      "Putty": "база",
      "Light body": "коррегирующий слой",
      "Activator": "активатор"
    },
    "option": "Putty",
    "price": 1182
  }
]