강의 목표 : 아래와 같은 화면을 class와 스타일 바인딩으로 좀 더 예쁘게 꾸며보자
쇼핑몰을 이렇게 꾸며놓고 오픈하면 바로 망한다..
1. variant div에 .color-circle
class를 추가한다.
//index.html
<div v-for="variant in variants"
:key="variant.id"
@mouseover="updateImage(variant.image)"
class="color-circle">
{{ variant.color }}
</div>
//style.css
.color-circle {
width: 50px;
height: 50px;
margin-top: 8px;
border: 2px solid #d8d8d8;
border-radius: 50%;
}
2. color-circle 클래스 옆에 v-bind로 스타일바인딩한다.
//index.html
<div v-for="variant in variants"
:key="variant.id"
@mouseover="updateImage(variant.image)"
class="color-circle"
//style binding 하기
:style = "{ backgroundColor: variant.color }"
>
</div>
결과
짜잔~ 글자 대신 색상 원이 나타남
반복문을 돌듯이 배경색을 뱉어낸다.
Camel vs. Kebab
- camel case : 두단어 사이를 붙이고 두번째 단어에 대문자 삽입 (마치 낙타 혹 같아서)
<div :style={ backgroundColor : variant.color}></div>
- kebab case : 단어 사이 '-' 삽입 ( 꼬챙로 고기 꽂은 케밥 같아서)
//틀린 예. 아래에서 자세히 설명 <div :style={ background-color : variant.color}></div>
backgroundColor
를 camel case가 아닌 kebab case로 사용한다면 자바스크립트가 마이너스 기호로 해석했을 것이다.<div :style={ 'background-color' : variant.color}></div>
만약에 여러개의 스타일을 사용하고 싶은데 한 줄로 주르륵 늘여놓으면 코드를 읽기 어려워진다. 이것을 어떻게 표현해야 할까?
: main.js의 데이터에 객체로 넣기
예제
//main.js
data(){
return{
styles:{
color: 'red',
fontSize:'14px'
margin-left: '50px';
padding: '20px';
}
}
}
//index.html
<div style="color: red; font-size: 14px; margin-left: 50px; padding: 20px"></div>
data의 스타일 객체 이름만 삽입해서 모든 스타일 객체 내용을 한번에 바인딩한다.
//index.html
<div style="styles"></div>
instock
data value가 false면 out of stock으로 바뀌는데 현 코드에는 아직도 카트의 숫자가 올라간다. 카드 숫자가 올라가지 않게 instock
이 false면 add to cart 가 disable 되게 만들자.
1. 굉장히 간단함. 버튼에 :disabled="!inStock"
추가
//index.html
<button
class="button"
:disabled="!inStock"
@click="addToCart">
Add to Cart
</button>
재고가 없으면 'Add to Cart'를 눌러도 장바구니의 갯수가 늘어나지 않는다. 하지만 아직도 'Add to Cart' 버튼을 눌러도 될 것 같아 보인다! 그러면 어떻게?
2. 클래스 바인딩을 이용하여 disabled 버튼 클래스를 추가한다.
//styles.css
.disabledButton {
background-color: #d8d8d8;
cursor: not-allowed;
}
//index.html
<button
class="button"
:class="{disabledButton: !inStock}"
:disabled="!inStock"
@click="addToCart">
Add to Cart
</button>
결과
누가봐도 재고 없어서 클릭버튼이 동작하지 않을 것 같이 생겼다.
실제로 마우스 커서를 addto cart에 올리면 금지 아이콘이🚫 뜬다
뷰 개발창, 혹은 console에서 mountedApp.inStock = true
로 변경하면 버튼이 다시 원래 색으로 돌아오면서 수량 추가를 할 수 있다.
클래스가 여러개 있는데 하나로 합치고 싶으면?
그냥 하나로 합쳐라.
<div class="color-circle"
:class="{active : activeClass}"></div>
//⬆️이 코드를 ⬇️이렇게
<div class="color-circle active"></div>
3항 연산자를 사용하여 조건에 따라 다른 클래스를 추가할 수 있는 기능
activeClass가 true
//activeClass 이름만 남기고 모두 생략 가능
<div class="activeClass"></div>
code challenge
1. Bind the out-of-stock-img
class to the image whenever inStock
is false
code challenge answer
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Vue Mastery</title>
<!-- Import Styles -->
<link rel="stylesheet" href="./assets/styles.css" />
<!-- Import Vue.js -->
<script src="https://unpkg.com/vue@3.0.11/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<div class="nav-bar"></div>
<div class="cart">Cart({{ cart }})</div>
<div class="product-display">
<div class="product-container">
<div class="product-image">
<!-- solution -->
<img :class="{ 'out-of-stock-img': !inStock }" v-bind:src="image">
<!-- solution -->
</div>
<div class="product-info">
<h1>{{ product }}</h1>
<p v-if="inStock">In Stock</p>
<p v-else>Out of Stock</p>
<ul>
<li v-for="detail in details">{{ detail }}</li>
</ul>
<div
v-for="variant in variants"
:key="variant.id"
@mouseover="updateImage(variant.image)"
class="color-circle"
:style="{ backgroundColor: variant.color }">
</div>
<button
class="button"
:class="{ disabledButton: !inStock }"
:disabled="!inStock"
@click="addToCart">
Add to Cart
</button>
</div>
</div>
</div>
</div>
<!-- Import App -->
<script src="./main.js"></script>
<!-- Mount App -->
<script>
const mountedApp = app.mount('#app')
</script>
</body>
</html>
//main.js
const app = Vue.createApp({
data() {
return {
cart:0,
product: 'Socks',
brand: 'Vue Mastery',
image: './assets/images/socks_blue.jpg',
inStock: false,
details: ['50% cotton', '30% wool', '20% polyester'],
variants: [
{ id: 2234, color: 'green', image: './assets/images/socks_green.jpg' },
{ id: 2235, color: 'blue', image: './assets/images/socks_blue.jpg' },
]
}
},
methods: {
addToCart() {
this.cart += 1
},
updateImage(variantImage) {
this.image = variantImage
}
}
})