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)