input 데이터 받기
ProductModal.vue
<template>
<div class="black-bg" v-if="onModal">
<div class="white-bg">
<input @input="month = $event.target.value" /> <!--1-->
<input v-model.number="month"> <!--2-->
<p>{{ productLists[productIndex].price * month }}</p>
</div>
</div>
</template>
<script>
export default {
name: "ProductModal",
data() {
return {
month: 1,
};
},
props: {
productLists: Array,
productIndex: Number,
},
};
</script>
- 인풋 태그를 만들고 다음과 같이 사용자의 입력을 month 데이터에 넣어줄 수 있습니다. "@input" 속성은 입력이 변할 때마다 적용되고 "@change"속성은 입력하고 사용자가 인풋 창을 벗어날 때 적용됩니다.
- 이렇게 "v-model" 속성으로 위와 똑같은 기능을 수행하는 코드를 작성할 수 있습니다. 이 속성은 정보를 받는 모든 태그에 적용이 가능합니다. 또 받아오는 데이터는 모두 문자열이기 때문에 속성 뒤에 타입을 지정해서 받을 수 있습니다.
watcher로 데이터 감시
ProductModal.vue
<template>
<div class="black-bg" v-if="onModal">
<div class="white-bg">
<img :src="productLists[productIndex].image" style="width: 100%" />
<h4>{{ productLists[productIndex].title }}</h4>
<p>{{ productLists[productIndex].content }}</p>
<input v-model.number="month">
<p>{{ productLists[productIndex].price * month }}</p>
<button @click="$emit('closeModal')">close</button>
</div>
</div>
</template>
<script>
export default {
name: "ProductModal",
data() {
return {
month: 1,
};
},
// 여기
watch : {
month(data, prevData) {
if(isNaN(data)) {
alert("숫자를 입력하세요!");
this.month = 1;
}
console.log(prevData);
}
},
props: {
productLists: Array,
productIndex: Number,
onModal: Boolean,
},
};
</script>
다음과 같이 데이터 이름과 같은 함수를 watch 보관함에 만들 수 있습니다. 이는 데이터가 변할 때마다 실행하는 함수를 의미하며 지금은 숫자 말고 다른 것을 입력했을 때 경고를 보내고 값을 1로 바꿉니다. 게다가 이 함수는 두 번째 인자로 데이터의 변하기 전 가장 최근 값을 불러올 수 있습니다.
모달 스타일 작업
App.vue
<template>
<!--2-->
<div class="start" :class="{ end: onModal }">
<ProductModal
:productLists="productLists"
:productIndex="productIndex"
:onModal="onModal"
@closeModal="onModal = false"
/>
</div>
</template>
<style>
body {
margin: 0;
}
div {
box-sizing: border-box;
}
#app {
// 1
.start {
opacity: 0;
transition: all 1s;
}
.end {
opacity: 1;
}
</style>
- 다음과 같이 클래스를 두 개 정의합니다.
- 동적으로 모달이 활성화되면 클래스에 "end"가 추가되게 합니다. "end" 속성은 옆 조건이 참일 경우에만 켜지게 됩니다.
App.vue
<template>
<transition name="fade">
<ProductModal
:productLists="productLists"
:productIndex="productIndex"
:onModal="onModal"
@closeModal="onModal = false"
/>
</transition>
</template>
<style>
.fade-enter-from {
opacity: 0;
}
.fade-enter-active {
transition: all 1s;
}
.fade-enter-to {
opacity: 1;
}
.fade-leave-from {
opacity: 1;
}
.fade-leave-active {
transition: all 1s;
}
.fade-leave-to {
opacity: 0;
}
</style>
Vue는 transition 태그를 이용하여 위와 똑같이 구현할 수 있습니다. 그리고 style에 name과 상황을 단계별로 나눠 그에 맞게 스타일을 부여할 수 있습니다.
상품 정렬
App.vue
<template>
<!--1-->
<button @click="priceUp">Price↑</button>
<button @click="priceDown">Price↓</button>
<button @click="sortBack">Reset</button>
<ProductCard
v-for="item in productLists"
:key="item.id"
:product="item"
:productIndex="productIndex"
@openModal="
onModal = true;
productIndex = $event;
"
/>
</template>
<script>
import data from "./assets/dummyData";
import ProductCard from "./components/ProductCard.vue";
export default {
name: "App",
data() {
return {
productListsCopy: [...data], // 2
productLists: data,
productIndex: 0,
onModal: false,
};
},
methods: {
// 1
priceUp() {
this.productLists.sort((a, b) => a.price - b.price);
},
priceDown() {
this.productLists.sort((a, b) => b.price - a.price);
},
// 2
sortBack() {
this.productLists = [...this.productListsCopy];
}
},
components: {
Discount: DiscountBanner,
ProductModal: ProductModal,
ProductCard: ProductCard,
},
};
</script>
- 버튼을 만들고 상품의 가격에 따라 정렬하는 함수를 만들어 연결해 줍니다.
- sort는 기존 배열을 바꿔버리기에 사본을 따로 만들어 저장하고 정렬을 해제할 때 그 사본을 넣어줍니다. 배열은 등호로 넣게 되면 값의 대입이 아닌 공유이기에 사본의 사본을 전달해 줍니다.
Vue의 라이프 사이클

- create 단계 - 데이터만 존재
- mount 단계 - template 태그 사이에 있던 HTML을 렌더링
- component 생성 단계
- update 단계- HTML의 실시간 리렌더링
- unmount 단계 - component 삭제
이렇게 간단하게 단계를 나눌 수 있지만 중요한 점은 위 사이클에서 빨간 점 선으로 표시된 훅들입니다. 이는 단계 사이사이마다 훅을 걸어 코드를 집어넣고 생성할 수 있게 됩니다.
App.vue
<template>
<Discount v-if="showDiscount" />
</template>
<script>
import data from "./assets/dummyData";
import DiscountBanner from "./components/DiscountBanner.vue";
export default {
name: "App",
data() {
return {
showDiscount: true,
};
},
methods: {},
created() {
// AJAX 요청
},
mounted() {
setTimeout(() => {
this.showDiscount = false;
}, 2000);
},
components: {
Discount: DiscountBanner,
},
};
</script>
Discount 컴포넌트가 마운트 되고 2초 후 사라지게 하는 코드입니다. script 태그 안에 훅을 설정해 주고 안에 실행할 코드를 넣어주면 됩니다. 보통 통신으로 데이터를 받을 때 created 훅이나 mounted 훅을 사용합니다. 또 그 외의 모든 단계 사이에 훅을 걸 수 있습니다.
'VUE' 카테고리의 다른 글
| Vuex (6) | 2023.04.21 |
|---|---|
| slot 과 mitt (7) | 2023.04.20 |
| Vue를 이용한 여러 기능 구현 (7) | 2023.04.19 |
| Vue 라우팅 (7) | 2023.04.17 |
| Vue 기초 1 (6) | 2023.04.13 |