Vue.js untuk pemula pelajaran 7: properti yang dihitung
→ Vue.js untuk pemula pelajaran 8: komponen
Tujuan pelajaran
Tujuan utama pelajaran ini adalah membuat komponen pertama kita dan menjelajahi mekanisme untuk meneruskan data ke komponen.
Kode awal
Berikut adalah kode file yang
index.html
ditemukan di tag yang <body>
akan kita mulai:
<div id="app">
<div class="product">
<div class="product-image">
<img :src="image" />
</div>
<div class="product-info">
<h1>{{ title }}</h1>
<p v-if="inStock">In stock</p>
<p v-else>Out of Stock</p>
<p>Shipping: {{ shipping }}</p>
<ul>
<li v-for="detail in details">{{ detail }}</li>
</ul>
<div
class="color-box"
v-for="(variant, index) in variants"
:key="variant.variantId"
:style="{ backgroundColor: variant.variantColor }"
@mouseover="updateProduct(index)"
></div>
<button
v-on:click="addToCart"
:disabled="!inStock"
:class="{ disabledButton: !inStock }"
>
Add to cart
</button>
<div class="cart">
<p>Cart({{ cart }})</p>
</div>
</div>
</div>
</div>
Ini kodenya
main.js
:
var app = new Vue({
el: '#app',
data: {
product: 'Socks',
brand: 'Vue Mastery',
selectedVariant: 0,
details: ['80% cotton', '20% polyester', 'Gender-neutral'],
variants: [
{
variantId: 2234,
variantColor: 'green',
variantImage: './assets/vmSocks-green.jpg',
variantQuantity: 10
},
{
variantId: 2235,
variantColor: 'blue',
variantImage: './assets/vmSocks-blue.jpg',
variantQuantity: 0
}
],
cart: 0,
},
methods: {
addToCart() {
this.cart += 1;
},
updateProduct(index) {
this.selectedVariant = index;
console.log(index);
}
},
computed: {
title() {
return this.brand + ' ' + this.product;
},
image() {
return this.variants[this.selectedVariant].variantImage;
},
inStock(){
return this.variants[this.selectedVariant].variantQuantity;
}
}
})
Tugas
Kami tidak membutuhkan semua data, metode, properti yang dihitung dalam aplikasi Vue untuk ditempatkan di instance root Vue. Seiring waktu, hal ini akan menyebabkan kode yang akan sangat sulit untuk dipertahankan. Sebaliknya, kami ingin membagi kode menjadi beberapa bagian yang lebih mudah digunakan dan membuat pengembangan lebih fleksibel.
Solusi dari masalah tersebut
Mari kita mulai dengan mengambil kode yang ada dan memindahkannya ke komponen baru.
Beginilah cara
main.js
komponen didaftarkan di file :
Vue.component('product', {})
Argumen pertama adalah nama komponen pilihan kita. Yang kedua adalah objek opsi yang mirip dengan yang kami gunakan untuk membuat instance Vue di tutorial sebelumnya.
Dalam contoh Vue, kami menggunakan properti
el
untuk mengatur pengikatannya ke elemen DOM. Dalam kasus komponen, properti digunakan template
yang mendefinisikan kode HTML komponen.
Mari kita gambarkan template komponen dalam sebuah objek dengan opsi:
Vue.component('product', {
template: `
<div class="product">
… // HTML-, product
</div>
`
})
Ada beberapa cara untuk membuat template di Vue. Kami sekarang menggunakan literal template, yang isinya diapit tanda kutip belakang.
Jika ternyata kode template tidak akan ditempatkan dalam satu elemen root, seperti elemen
<div>
dengan kelas product
, ini akan menghasilkan pesan kesalahan berikut:
Component template should contain exactly one root element
Dengan kata lain, template komponen hanya dapat mengembalikan satu elemen.
Misalnya, template berikut ini dibentuk dengan baik karena hanya diwakili oleh satu elemen:
Vue.component('product', {
template: `<h1>I'm a single element!</h1>`
})
Tetapi jika template berisi beberapa saudara, itu tidak akan berfungsi. Berikut contoh pola yang buruk:
Vue.component('product', {
template: `
<h1>I'm a single element!</h1>
<h2>Not anymore</h2>
`
})
Hasilnya, ternyata jika template harus menyertakan banyak elemen, misalnya, sekumpulan elemen yang disertakan dalam
<div>
kelas kita product
, elemen ini harus ditempatkan di elemen container luar. Hasilnya, template hanya akan memiliki satu elemen root.
Sekarang template berisi kode HTML yang dulu ada di file
index.html
, kita bisa menambahkan data, metode, properti yang dihitung ke komponen yang sebelumnya ada di instance root Vue:
Vue.component('product', {
template: `
<div class="product">
…
</div>
`,
data() {
return {
//
}
},
methods: {
//
},
computed: {
//
}
})
Seperti yang Anda lihat, struktur komponen ini hampir persis sama dengan struktur instance Vue yang kita kerjakan sebelumnya. Pernahkah Anda memperhatikan bahwa
data
ini sekarang bukan properti, tetapi metode objek dengan opsi? Mengapa demikian?
Intinya adalah bahwa komponen sering kali dibuat dengan rencana untuk digunakan kembali. Jika kita memiliki banyak komponen
product
, kita perlu memastikan bahwa masing-masing memiliki contoh entitasnya sendiri data
. Karena data
sekarang merupakan fungsi yang mengembalikan objek dengan data, setiap komponen dijamin untuk menerima kumpulan datanya sendiri. Jika entitas data
bukanlah sebuah fungsi, maka setiap komponenproduct
, dimanapun komponen tersebut digunakan, akan berisi data yang sama. Ini bertentangan dengan gagasan komponen yang dapat digunakan kembali.
Sekarang setelah kita memindahkan kode terkait produk ke dalam komponen asli
product
, kode untuk mendeskripsikan instance root Vue terlihat seperti ini:
var app = new Vue({
el: '#app'
})
Sekarang kita hanya perlu menempatkan komponen
product
dalam kode file index.html
. Ini akan terlihat seperti ini:
<div id="app">
<product></product>
</div>
Jika Anda memuat ulang halaman aplikasi sekarang, itu akan kembali ke bentuk sebelumnya.
Halaman Aplikasi
Jika Anda sekarang melihat ke alat pengembang Vue, Anda akan melihat bahwa ada entitas Root dan komponen Produk.
Menganalisis Aplikasi dengan Alat Pengembang Vue
Sekarang, hanya untuk mendemonstrasikan kegunaan kembali komponen, mari tambahkan
index.html
beberapa komponen lagike kodeproduct
. Faktanya, ini adalah bagaimana penggunaan kembali komponen diatur. Kode tersebutindex.html
akan terlihat seperti ini:
<div id="app">
<product></product>
<product></product>
<product></product>
</div>
Dan halaman tersebut akan menampilkan tiga salinan dari kartu produk.
Beberapa product card terpampang pada satu halaman
Harap diperhatikan bahwa kedepannya kita akan bekerja dengan satu komponen
product
, sehingga kodenyaindex.html
akan terlihat seperti ini:
<div id="app">
<product></product>
</div>
Tugas
Aplikasi seringkali membutuhkan komponen untuk menerima data, parameter input, dari entitas induk. Dalam kasus ini, induk dari komponen tersebut
product
adalah instance root Vue itu sendiri.
Biarkan instance root Vue memiliki deskripsi beberapa data. Data ini menunjukkan apakah pengguna adalah pemegang akun premium. Kode untuk mendeskripsikan instance Vue mungkin terlihat seperti ini:
var app = new Vue({
el: '#app',
data: {
premium: true
}
})
Mari kita putuskan bahwa pengguna premium berhak atas pengiriman gratis.
Ini berarti bahwa kita ingin komponen
product
mengeluarkan premium
informasi biaya pengiriman yang berbeda , bergantung pada apa yang tertulis ke properti root Vue instance.
Bagaimana saya bisa mengirim data yang disimpan dalam properti
premium
root Vue instance ke anak yang merupakan komponennya product
?
Solusi dari masalah tersebut
Di Vue, untuk mentransfer data dari entitas induk ke anak-anak, properti objek dengan opsi yang
props
dijelaskan oleh komponen digunakan. Ini adalah objek dengan deskripsi parameter input komponen, yang nilainya harus ditetapkan berdasarkan data yang diterima dari entitas induk.
Mari kita mulai dengan menjelaskan jenis parameter input yang diharapkan akan diterima komponen
product
. Untuk melakukan ini, tambahkan properti yang sesuai ke objek dengan opsi yang digunakan saat membuatnya:
Vue.component('product', {
props: {
premium: {
type: Boolean,
required: true
}
},
// , ,
})
Perhatikan bahwa ini menggunakan kemampuan bawaan Vue untuk memvalidasi parameter yang diteruskan ke sebuah komponen. Yaitu, kita menunjukkan apa jenis parameter masukan
premium
adalah Boolean
dan parameter ini apa yang dibutuhkan oleh pengaturan required
untuk true
.
Selanjutnya, mari buat perubahan pada template yang menampilkan parameter yang diteruskan ke objek. Dengan menampilkan nilai properti
premium
di halaman, kami akan memastikan bahwa mekanisme yang kami selidiki berfungsi dengan benar.
<p>User is premium: {{ premium }}</p>
Sejauh ini, semuanya baik-baik saja. Komponen
product
mengetahui bahwa ia akan menerima parameter tipe yang diperlukan untuk operasinya Boolean
. Kami telah menyiapkan tempat untuk menampilkan data yang relevan.
Tapi kami belum mengirimkan parameter ke
premium
komponen. Anda dapat melakukannya dengan menggunakan atribut khusus yang mirip dengan "garis" yang mengarah ke komponen yang memungkinkan untuk mengirimkan parameter masukan, dan secara khusus premium
.
Mari ubah kode di
index.html
:
<div id="app">
<product :premium="premium"></product>
</div>
Mari segarkan halaman.
Mengeluarkan data yang diteruskan ke komponen
Parameter masukan sekarang diteruskan ke komponen. Mari kita bicara tentang apa yang baru saja kita lakukan.
Kami meneruskan komponen sebuah parameter input, atau disebut "atribut khusus"
premium
. Kami mengikat atribut khusus ini menggunakan konstruksi titik dua ke propertipremium
yang disimpan dalam data instance Vue kami.
Sekarang instance root Vue dapat diteruskan ke
premium
komponen anakproduct
. Karena atribut terikat ke propertipremium
dari data instance Vue, nilai saat inipremium
akan selalu diteruskan ke komponenproduct
.
Angka di atas yaitu prasasti
User is premium: true
membuktikan bahwa segala sesuatunya dilakukan dengan benar.
Sekarang kami telah memverifikasi bahwa mekanisme transfer data yang kami pelajari berfungsi seperti yang diharapkan. Jika Anda melihat ke dalam alat pengembang Vue, ternyata komponen tersebut
Product
sekarang memiliki parameter input premium
yang menyimpan nilai true
.
Parameter Input dari Komponen
Setelah data tentang apakah pengguna memiliki akun premium masuk ke dalam komponen, mari gunakan data ini untuk menampilkan informasi biaya pengiriman pada halaman. Jangan lupa bahwa jika parameter
premium
disetel ke nilaitrue
, pengguna berhak mendapatkan pengiriman gratis. Mari buat properti komputasi barushipping
dan gunakan parameter di dalamnyapremium
:
shipping() {
if (this.premium) {
return "Free";
} else {
return 2.99
}
}
Jika
this.premium
disimpan dalam parameter true
, properti yang dihitung shipping
akan dikembalikan Free
. Kalau tidak, itu akan kembali 2.99
.
Mari hapus kode output nilai parameter dari template komponen
premium
. Sekarang elemen <p>Shipping: {{ shipping }}</p>
yang ada dalam kode yang kita mulai hari ini akan dapat menampilkan informasi tentang biaya pengiriman.
Pengguna premium mendapatkan
teks pengiriman gratis
Shipping: Free
muncul di halaman karena fakta bahwa komponen ditransmisikan parameter masukan yangpremium
ditetapkan ke nilaitrue
.
Hebat! Sekarang kami telah mempelajari cara mentransfer data dari entitas induk ke anak dan dapat menggunakan data ini di komponen untuk mengelola biaya pengiriman barang.
Ngomong-ngomong, perlu diperhatikan bahwa Anda tidak boleh mengubah parameter inputnya di komponen anak.
Bengkel
Buat komponen baru
product-details
yang harus menggunakan parameter input details
dan bertanggung jawab untuk rendering bagian dari kartu produk yang sebelumnya dibentuk menggunakan kode berikut:
<ul>
<li v-for="detail in details">{{ detail }}</li>
</ul>
Berikut adalah template yang dapat Anda gunakan untuk mengatasi masalah ini.
Inilah solusi untuk masalah tersebut.
Hasil
Hari ini adalah perkenalan pertama Anda dengan komponen Vue. Inilah yang Anda pelajari:
- Komponen adalah blok kode yang disajikan sebagai elemen khusus.
- Komponen membuat aplikasi Anda lebih mudah dikelola dengan memecahnya menjadi beberapa bagian yang dapat digunakan kembali. Mereka berisi deskripsi dari komponen visual dan fungsionalitas dari bagian aplikasi yang sesuai.
- Data komponen diwakili oleh metode
data()
objek dengan opsi. - Parameter input (
props
) digunakan untuk meneruskan data dari entitas induk ke entitas anak . - Kami dapat menjelaskan persyaratan untuk parameter input yang dibutuhkan komponen.
- .
- .
- Vue .
Apakah Anda menggunakan alat pengembang Vue?
→ Vue.js pemula pelajaran 1: contoh Vue
→ Vue.js untuk pemula, pelajaran 2: mengikat atribut
→ Vue.js pemula pelajaran 3: rendering bersyarat
→ Vue.js pemula pelajaran 4: daftar rendering
→ Vue .js untuk pemula pelajaran 5: pemrosesan acara
→ Pelajaran pemula Vue.js 6: mengikat kelas dan gaya
→ Pelajaran pemula Vue.js 7: properti yang dihitung
→ Pelajaran pemula Vue.js 8: komponen