Now that the category menu is completed, continue by implementing the product listing using the same tools as depicted in this diagram by completing the following steps:
- Implement the ProductCard component:
- Create the file /src/components/market/ProductCard.vue
- Write the following code:
<template>
<div class="item-card">
<div class="item-card-content-container">
<img class="item-card-content-container-img" :src="primaryImageSrc" />
<span class="item-card-content-container-title">{{product.title}}</span>
<span class="item-card-content-container-text">
{{product.description}}
</span>
</div>
</div>
</template>
<script>
export default {
name: 'ProductCard',
props: {
product: Object,
},
computed: {
primaryImageSrc: function() {
return this.product && this.product.media && this.product.media.length > 0
? this.product.media[0].url
: null;
}
},
}
</script>
<style scoped>
.item-card {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
background-color: white;
width: 280px;
height: 200px;
float: left;
margin: 10;
}
.item-card:hover {
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
.item-card-content-container {
padding: 2px 16px;
display: flex;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
}
.item-card-content-container-img {
display: block;
max-width: 80px;
max-height: 80px;
width: auto;
height: auto;
text-align: center;
}
.item-card-content-container-title {
display: block;
font-size: 1.6rem;
}
.item-card-content-container-text {
word-wrap: normal;
font-size: 1.2rem;
overflow: hidden;
}
</style>
- Implement the ProductList component:
- Create the file /src/components/market/ProductList.vue
- Write the following code:
<template>
<div>
<ul class="products-container">
<li v-for="p in products" :key="p.productId">
<ProductCard :product="p" />
</li>
</ul>
</div>
</template>
<script>
import ProductCard from './ProductCard.vue';
export default {
name: 'ProductList',
components: {
ProductCard,
},
props: {
products: Array,
},
}
</script>
<style scoped>
ul, li {
list-style: none;
padding: 0;
margin: 0;
display: inline;
}
.products-container {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
</style>
- Modify the ProductsPage component:
- Add an empty products array as the default starting data
- Load products when the selected category changes
- Import and render the ProductList component, as shown in the following example:
<template>
<div>
<CategoryMenu
:categories="categories"
@category-changed="onCategoryChanged"
/>
<ProductList :products="products" />
</div>
</template>
<script>
import MarketService from '../../services/marketService';
import CategoryMenu from './CategoryMenu.vue';
import ProductList from './ProductList.vue';
export default {
name: 'ProductsPage',
components: {
CategoryMenu,
ProductList,
},
data: () => ({
categories: [],
products: [],
}),
async created() {
this.categories = await MarketService.loadCategories();
},
methods: {
onCategoryChanged: async function(category) {
this.products = await MarketService.loadProducts(category.name);
},
},
}
</script>
That's it! You have just completed implementing the product listing, so go ahead and run the app to see it in action. It should look similar to this: