Skip to content

Commit e29bd3c

Browse files
committed
custom components: props & events
1 parent 87d6dd3 commit e29bd3c

File tree

4 files changed

+130
-7
lines changed

4 files changed

+130
-7
lines changed

01-HelloWorld/01-Socks.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
<html>
33
<head>
44
<script src="https://unpkg.com/vue"></script>
5-
<link href="./assets/style.css" rel="stylesheet" type="text/css">
6-
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
5+
<link href="./assets/style.css" rel="stylesheet">
6+
<link href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" rel="stylesheet">
7+
<title>Basic Socks</title>
78
</head>
89
<body>
910
<div id="app">
@@ -59,7 +60,7 @@ <h1>{{ product }}</h1>
5960
</div>
6061
</div>
6162

62-
<a href="02-FancierSocks.html" class="next">
63+
<a href="02-ComputedSocks.html" class="next">
6364
moving on <i class="fas fa-arrow-right"></i>
6465
</a>
6566
</body>
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<html>
22
<head>
33
<script src="https://unpkg.com/vue"></script>
4-
<link href="./assets/style.css" rel="stylesheet" type="text/css">
5-
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
4+
<link href="./assets/style.css" rel="stylesheet">
5+
<link href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" rel="stylesheet">
6+
<title>Computed Socks</title>
67
</head>
78
<body>
89
<div id="app">
@@ -52,6 +53,9 @@ <h1>{{ title }}</h1>
5253
<a href="01-Socks.html" class="prev">
5354
<i class="fas fa-arrow-left"></i> moving back
5455
</a>
56+
<a href="03-ComponentSocks.html" class="next">
57+
moving on <i class="fas fa-arrow-right"></i>
58+
</a>
5559
</body>
5660
</html>
5761

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<html>
2+
<head>
3+
<script src="https://unpkg.com/vue"></script>
4+
<link href="./assets/style.css" rel="stylesheet">
5+
<link href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" rel="stylesheet">
6+
<title>Componentized Socks</title>
7+
</head>
8+
<body>
9+
<div id="app">
10+
<div class="nav-bar"></div>
11+
12+
<product :premium="premium" @add-to-cart="updateCart"></product>
13+
14+
<div class="cart">
15+
{{ cart.length }}
16+
<i class="fas fa-shopping-cart"></i>
17+
</div>
18+
</div>
19+
20+
<a href="02-ComputedSocks.html" class="prev">
21+
<i class="fas fa-arrow-left"></i> moving back
22+
</a>
23+
</body>
24+
</html>
25+
26+
27+
<script type="text/javascript">
28+
const comp = Vue.component('product', {
29+
// Props with validation
30+
props: {
31+
premium: {type: Boolean, required: true, default: false}
32+
},
33+
// Without validation
34+
// props: ['premium'],
35+
template: `
36+
<div class="product">
37+
<div class="product-image">
38+
<img :src="image">
39+
</div>
40+
41+
<div class="product-info">
42+
<h1>{{ product }}</h1>
43+
44+
<div>
45+
<p v-if="inventory > 10">In Stock</p>
46+
<p v-else-if="inventory">Almost sold out</p>
47+
<p v-else>Out of Stock</p>
48+
</div>
49+
50+
<p v-if="premium">FREE Shipping</p>
51+
<p v-else>Shipping: $4.99</p>
52+
53+
<button
54+
v-on:click="addToCart"
55+
:disabled="!inventory"
56+
:class="inventory ? '' : 'disabledButton'"
57+
>
58+
Add to Cart
59+
</button>
60+
61+
<div v-for="(variant, index) in variants"
62+
:key="variant.id"
63+
class="color-box"
64+
:style="{backgroundColor: variant.color}"
65+
@mouseover="setSelectedVariant(variant, index)">
66+
</div>
67+
</div>
68+
</div>
69+
`,
70+
data() {
71+
// Return a fresh object reference each time
72+
return {
73+
product: 'Socks',
74+
selectedVariantIndex: 0,
75+
variants: [
76+
{id: 1, color: 'green'},
77+
{id: 2, color: 'blue'}
78+
],
79+
inventory: 3,
80+
}
81+
},
82+
methods: {
83+
addToCart() {
84+
this.inventory--;
85+
const selectedVariant = this.variants[this.selectedVariantIndex];
86+
this.$emit('add-to-cart', {product: this.product, variant: selectedVariant});
87+
},
88+
setSelectedVariant(variant, index) {
89+
this.selectedVariantIndex = index;
90+
}
91+
},
92+
computed: {
93+
image() {
94+
const color = this.variants[this.selectedVariantIndex].color;
95+
return `./assets/socks-${color}.jpg`;
96+
}
97+
}
98+
})
99+
100+
const app = new Vue({
101+
el: '#app',
102+
data: {
103+
premium: true,
104+
cart: []
105+
},
106+
methods: {
107+
updateCart(product) {
108+
console.log('Adding to cart:', product);
109+
this.cart.push(product);
110+
}
111+
}
112+
});
113+
</script>
114+
115+
116+
<!-- livereload -->
117+
<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1"></' + 'script>')</script>

01-HelloWorld/assets/style.css

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,15 @@ img {
5353
}
5454

5555
button {
56-
margin-top: -95px;
57-
float: right;
5856
border: none;
5957
background-color: #1E95EA;
6058
color: white;
6159
height: 40px;
6260
width: 100px;
6361
font-size: 14px;
62+
position: absolute;
63+
top: 85px;
64+
right: 13px;
6465
}
6566

6667
.disabledButton {

0 commit comments

Comments
 (0)