W pierwszym artykule z serii wpisów o Vue, wprowadziłem Cię w podstawowe informacje o komponentach oraz zarządzaniu ich wewnętrznym stanem. Spróbujmy wykorzystać naszą wiedzę do stworzenia re-używalnych komponentów.
Przyjmijmy, że mamy tablicę z informacjami o produktach. Stworzymy prosty komponent, który pozwoli nam wyświetlić sformatowane dane z użyciem pętli v-for
. Nasz komponent przyjmie jako props
obiekt opisujący dany produkt. Stwórzmy więc, nowy plik z poniższym kodem:
// Product.vue
<template>
<div class="product">
<figure class="product-image">
<img :src="productData.image" alt="Image" />
</figure>
<h4 class="product-name">{{ productData.name }}</h4>
<p class="product-price">{{ productData.price }} zł</p>
<button @click="addToCart">Dodaj</button>
</div>
</template>
<script>
export default {
name: 'product-item',
props: {
productData: Object
},
methods: {
addToCart() {
this.$emit('add', this.productData.id);
}
}
};
</script>
<style lang="scss">
.product {
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 5px;
padding: 1em;
margin: 1em;
}
.product-image {
max-width: 100%;
height: auto;
}
</style>
Następnie zmieńmy zawartość pliku HelloWorld.vue
na poniższą i przeanalizujmy co się dzieje.
<template>
<div class="products">
<product
v-for="product in products"
:product-data="product"
:key="product.id"
@add="onAddToCart"
/>
</div>
</template>
<script>
import Product from './Product';
export default {
name: 'HelloWorld',
components: {
Product
},
data() {
return {
products: [
{
id: 'sdfsdfd',
name: 'Stół',
price: 234.3
},
{
id: 'dsfsdfd',
name: 'Krzesło',
price: 34.0
},
{
id: 'dsfdfdf',
name: 'Łózko',
price: 1234.5
},
{
id: 'swebvb',
name: 'Lampka',
price: 4.3
},
{
id: 'dfdf34',
name: 'Półka',
price: 23.0
}
]
};
},
methods: {
onAddToCart(product) {
console.log('Product id: ', product);
}
}
};
</script>
<style lang="scss">
.products {
display: flex;
flex-wrap: wrap;
}
</style>
Komponent Product.vue
, nie robi nic oprócz wyświetlania naszych danych oraz emitowania eventu na kliknięcie. Emitowanie własnych eventów nie zostało dotychczas omówione, więc teraz dwa słowa o nim.
Vue dostarcza nam metodę $emit
, która jako pierwszy parametr przyjmuje nazwę eventu, pod którą można nasłuchiwać na własne zdarzenie, a jako drugi dane, które zostaną przekazane do funkcji podpiętej do listenera.
Emitowany event jest "do złapania" tylko w rodzicu. W tym celu należy w rodzicu poprzedzić nazwę eventu, który będzie nasłuchiwany znakiem @
(która jest skrótem do dyrektywy v-on), a następnie przypisać funkcję, która zostanie wywołana po wyemitowaniu eventu.
Należy pamiętać o zachowaniu tej samej nazwy przy emitowaniu i nasłychiwaniu eventu (szczegóły w dokumentacji).
Właśnie w taki sposób w pliku HelloWorld.vue
została pobrana informacja, który produkt dodać do koszyka (w parametrze eventu przekazuję id
produktu). Zauważ też, że dyrektywa v-for
została użyta na komponencie, który ma być powtarzany.
Przedstawiony przykład pokazuje podstawy kompozycji i tworzenia zależności przy pomocy re-używalnych komponentów. Jest to dobry moment do zatrzymania się na dłuższą chwilę i utrwalenia poznanych funkcjonalosci komponentów Vue. Polecam wykonanie kilku ćwiczeń polegających na komponowaniu widoków z własnych komponenów np. przez utworzenie formularza, w którym zostaną stworzone nowe produkty.