Home > database >  How to outputting data from 2 arrays to a product card using Vue 3 js
How to outputting data from 2 arrays to a product card using Vue 3 js

Time:10-22

There is data received from Vuex.
These are products and brands. Products and brands are 2 different arrays but with similar values in the keys. On the product card, I need to display the brand name (brand.title) in accordance with the condition product.brand === brand.id

Data from products array:

{
  "products" : [
    {
      "type": "simple",
      "id": 1,
      "sku": "s1",
      "title": "Product 1",
      "regular_price": {
        "currency": "USD",
        "value": 27.12
      },
      "image": "/images/1.png",
      "brand": 9
    },
    {
      "type": "simple",
      "id": 2,
      "sku": "s2",
      "title": "Product 2",
      "regular_price": {
        "currency": "USD",
        "value": 36.87
      },
      "image": "/images/2.png",
      "brand": 8
    },
    {
      "type": "simple",
      "id": 3,
      "sku": "s3",
      "title": "Product 3",
      "regular_price": {
        "currency": "USD",
        "value": 28.91
      },
      "image": "/images/3.png",
      "brand": 2
    },
    {
      "type": "simple",
      "id": 4,
      "sku": "s4",
      "title": "Product 4",
      "regular_price": {
        "currency": "USD",
        "value": 41.23
      },
      "image": "/images/4.png",
      "brand": 7
    },
    {
      "type": "simple",
      "id": 5,
      "sku": "s5",
      "title": "Product 5",
      "regular_price": {
        "currency": "USD",
        "value": 88.00
      },
      "image": "/images/5.png",
      "brand": 3
    },
    {
      "type": "simple",
      "id": 6,
      "sku": "s6",
      "title": "Product 6",
      "regular_price": {
        "currency": "USD",
        "value": 127.41
      },
      "image": "/images/6.png",
      "brand": 6
    },
    {
      "type": "simple",
      "id": 7,
      "sku": "s7",
      "title": "Product 7",
      "regular_price": {
        "currency": "USD",
        "value": 123.40
      },
      "image": "/images/7.png",
      "brand": 5
    },
    {
      "type": "simple",
      "id": 8,
      "sku": "s8",
      "title": "Product 8",
      "regular_price": {
        "currency": "USD",
        "value": 92.32
      },
      "image": "/images/8.png",
      "brand": 1
    },
    {
      "type": "simple",
      "id": 9,
      "sku": "s9",
      "title": "Product 9",
      "regular_price": {
        "currency": "USD",
        "value": 53.40
      },
      "image": "/images/9.png",
      "brand": 2
    }
  ]
}

Data from brands:

{
  "brands" : [
    {
      "id": 1,
      "title": "Brand 1",
      "sort": "100",
      "code": "brand_1"
    },
    {
      "id": 2,
      "title": "Brand 2",
      "sort": "200",
      "code": "brand_2"
    },
    {
      "id": 3,
      "title": "Brand 3",
      "sort": "300",
      "code": "brand_3"
    },
    {
      "id": 4,
      "title": "Brand 4",
      "sort": "400",
      "code": "brand_4"
    },
    {
      "id": 5,
      "title": "Brand 5",
      "sort": "500",
      "code": "brand_5"
    },
    {
      "id": 6,
      "title": "Brand 6",
      "sort": "600",
      "code": "brand_6"
    },
    {
      "id": 7,
      "title": "Brand 7",
      "sort": "700",
      "code": "brand_7"
    },
    {
      "id": 8,
      "title": "Brand 8",
      "sort": "700",
      "code": "brand_8"
    },
    {
      "id": 9,
      "title": "Brand 9",
      "sort": "900",
      "code": "brand_9"
    }
  ]
}

Main page code:

<template>
  <section >
    <div >
      <h1 >
        Сatalog
      </h1>
      <div >

        <div >
          <div >
            <div >
              <filter-category
              :brands="BRANDS"
              @selectBrand="selectBrand"
              />
            </div>
          </div>
        </div>

        <div >
          <div >
            <catalog-item
                v-for="product in filteredProducts"
                :key="product.id"
                :product_data="product"
                @addToCart="addToCart"
            />
          </div>
        </div>

      </div>
    </div>
</section>
</template>

<script>
import CatalogItem from "@/components/catalog/CatalogItem";
import FilterCategory from "@/components/UI/FilterCategory";
import {mapActions, mapGetters} from 'vuex'

export default {
  name: "MainPage",
  components: {
    CatalogItem,
    FilterCategory,
  },
  data() {
    return {
      sortedProducts:[],
    }
  },
  computed: {
    ...mapGetters([
        'PRODUCTS',
        'BRANDS',
    ]),
    filteredProducts() {
      if (this.sortedProducts.length) {
        return this.sortedProducts
      } else {
        return this.PRODUCTS
      }
    }
  },
  methods: {
    ...mapActions([
        'GET_PRODUCTS_FROM_API',
        'GET_BRANDS_FROM_API',
        'ADD_TO_CART'
    ]),
    addToCart(data) {
      this.ADD_TO_CART(data)
    },
    selectBrand(brand) {
      this.sortedProducts = []
      let vm = this
      this.PRODUCTS.map((item) => {
        if(item.brand === brand.id) {
          vm.sortedProducts.push(item)
        }
      })
    },

  },
  mounted() {
    this.GET_PRODUCTS_FROM_API()
    this.GET_BRANDS_FROM_API()
  }
}
</script>

<style lang="scss">

.catalog-section__title {
  margin: 0 0 20px;
  color: #000;
  font-weight: 400;
  font-style: normal;
  font-stretch: normal;
  font-size: 44px;
  line-height: 1.2;
  letter-spacing: normal;
  text-align: left;
}

.catalog-content {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 50px;
}

.catalog-content__aside {
  width: 100%;
  max-width: 380px;
  margin-right: 10px;
}

.catalog-filter {
  width: 100%;
  display: flex;
  flex-direction: column;
  height: 100%;
}

.catalog-filter__category {
  height: 100%;
  padding: 35px 55px;
  background: white;
  color: #000000;
  font-weight: 400;
  font-style: normal;
  font-stretch: normal;
  font-size: 16px;
  line-height: 1.88;
  letter-spacing: normal;
  text-align: left;
}

.catalog-filter__category-list {
  display: flex;
  flex-direction: column;
}

.catalog-content__products {
  width: 100%;

  .catalog-content__products-list {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-gap: 10px;
  }
}

</style>

Catalog item code:

<template>
  <div >
    <router-link
        
        to=""
    >
      <img
          :src=" require('../../assets'   product_data.image) "
          alt="img"
      >
    </router-link>
    <router-link
        
        to=""
    >
        {{ product_data.title }}
    </router-link>
    <div >
      <brand-title
        :product_brand="product_data.brand"
      />
    </div>
    <div >
      <router-link
          to=""
          
      >
        <b>
          {{ product_data.regular_price.value }}
           <span>
            {{ product_data.regular_price.currency }}
          </span>
        </b>
      </router-link>
      <router-link
          
          to="" >
<!--        <img src="../assets/image/card-cart.svg" alt="card-cart-icon">-->
        <svg
            @click="addToCart"
            height="24"
            width="24"
            viewBox="0 -31 512.00026 512"
             xmlns="http://www.w3.org/2000/svg">
          <path
              d="m164.960938 300.003906h.023437c.019531 0 .039063-.003906.058594-.003906h271.957031c6.695312 0 12.582031-4.441406 14.421875-10.878906l60-210c1.292969-4.527344.386719-9.394532-2.445313-13.152344-2.835937-3.757812-7.269531-5.96875-11.976562-5.96875h-366.632812l-10.722657-48.253906c-1.527343-6.863282-7.613281-11.746094-14.644531-11.746094h-90c-8.285156 0-15 6.714844-15 15s6.714844 15 15 15h77.96875c1.898438 8.550781 51.3125 230.917969 54.15625 243.710938-15.941406 6.929687-27.125 22.824218-27.125 41.289062 0 24.8125 20.1875 45 45 45h272c8.285156 0 15-6.714844 15-15s-6.714844-15-15-15h-272c-8.269531 0-15-6.730469-15-15 0-8.257812 6.707031-14.976562 14.960938-14.996094zm312.152343-210.003906-51.429687 180h-248.652344l-40-180zm0 0" />
          <path
              d="m150 405c0 24.8125 20.1875 45 45 45s45-20.1875 45-45-20.1875-45-45-45-45 20.1875-45 45zm45-15c8.269531 0 15 6.730469 15 15s-6.730469 15-15 15-15-6.730469-15-15 6.730469-15 15-15zm0 0" />
          <path
              d="m362 405c0 24.8125 20.1875 45 45 45s45-20.1875 45-45-20.1875-45-45-45-45 20.1875-45 45zm45-15c8.269531 0 15 6.730469 15 15s-6.730469 15-15 15-15-6.730469-15-15 6.730469-15 15-15zm0 0" />
        </svg>
      </router-link>
    </div>
  </div>
</template>

<script>
import BrandTitle from "@/components/UI/BrandTitle";
export default {
  name: "CatalogItem",
  components: {
    BrandTitle
  },
  props: {
    product_data: {
      type: Object,
      default() {
        return {};
      },
    },

  },

  methods: {
    addToCart() {
      this.$emit('addToCart', this.product_data)
    }
  },

}
</script>

<style lang="scss">
.catalog-card {
  display: grid;
  background: #fff;
  padding: 20px;
  transition: .3s;
  &:hover {
    box-shadow: 0 10px 10px 0 rgba(98, 62, 99, 0.1);
  }

  &__img {
    display: block;
    width: 100%;
    position: relative;
    padding-top: 100%;
    margin-bottom: 19px;
    img {
      width: 100%;
      height: 100%;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      object-fit: contain;
      object-position: center;
    }
  }
  &__title{
    font-size: 16px;
    font-weight: normal;
    font-stretch: normal;
    font-style: normal;
    line-height: 1.25;
    letter-spacing: normal;
    text-align: left;
    color: #000;
    //min-height: 30px;
    display: -webkit-box;
    white-space: normal;
    -o-text-overflow: ellipsis;
    text-overflow: ellipsis;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    overflow: hidden;
    margin-bottom: 5px;
  }

  &__brand {
    margin-bottom: 15px;
  }

  &__price-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  &__price {
    font-size: 18px;
    font-weight: 600;
    font-stretch: normal;
    font-style: normal;
    line-height: 1.22;
    letter-spacing: normal;
    text-align: left;
    color: #000;

    b span {
      font-size: 17px;
    }
  }

  &__cart {
    display: flex;
    justify-content: center;
    align-items: center;

    svg {
      fill: #bcbcc6;
      transition: 0.3s;
    }

    &:hover {
      svg {
        fill: black;
      }
    }
  }
}
</style>

CodePudding user response:

Try to create computed property and map products with brand title:

const products = [{"type": "simple", "id": 1, "sku": "s1", "title": "Product 1", "regular_price": {"currency": "USD", "value": 27.12}, "image": "/images/1.png", "brand": 9}, {"type": "simple", "id": 2, "sku": "s2", "title": "Product 2", "regular_price": {"currency": "USD", "value": 36.87}, "image": "/images/2.png", "brand": 8}, {"type": "simple", "id": 3, "sku": "s3", "title": "Product 3", "regular_price": {"currency": "USD", "value": 28.91}, "image": "/images/3.png", "brand": 2}, {"type": "simple", "id": 4, "sku": "s4", "title": "Product 4", "regular_price": {"currency": "USD", "value": 41.23}, "image": "/images/4.png", "brand": 7}, {"type": "simple", "id": 5, "sku": "s5", "title": "Product 5", "regular_price": {"currency": "USD", "value": 88.00}, "image": "/images/5.png", "brand": 3}, {"type": "simple", "id": 6, "sku": "s6", "title": "Product 6", "regular_price": {"currency": "USD", "value": 127.41}, "image": "/images/6.png", "brand": 6}, {"type": "simple", "id": 7, "sku": "s7", "title": "Product 7", "regular_price": {"currency": "USD", "value": 123.40}, "image": "/images/7.png", "brand": 5}, {"type": "simple", "id": 8, "sku": "s8", "title": "Product 8", "regular_price": {"currency": "USD", "value": 92.32}, "image": "/images/8.png", "brand": 1}, {"type": "simple", "id": 9, "sku": "s9", "title": "Product 9", "regular_price": {"currency": "USD", "value": 53.40}, "image": "/images/9.png", "brand": 12}]

const brands = [{"id": 1, "title": "Brand 1", "sort": "100", "code": "brand_1"}, {"id": 2, "title": "Brand 2", "sort": "200", "code": "brand_2"}, {"id": 3, "title": "Brand 3", "sort": "300", "code": "brand_3"}, {"id": 4, "title": "Brand 4", "sort": "400", "code": "brand_4"}, {"id": 5, "title": "Brand 5", "sort": "500", "code": "brand_5"}, {"id": 6, "title": "Brand 6", "sort": "600", "code": "brand_6"}, {"id": 7, "title": "Brand 7", "sort": "700", "code": "brand_7"}, {"id": 8, "title": "Brand 8", "sort": "700", "code": "brand_8"}, {"id": 9, "title": "Brand 9", "sort": "900", "code": "brand_9"}]

const res = products.map(p => {
  const br = brands.find(b => b.id === p.brand)
  return {...p, brandtitle: br?.title || 'no brand'}
})
console.log(res)

  • Related