본 내용은 인프런 장기효(캡틴판교)님의 Vue.js 중급 강좌 - 웹앱 제작으로 배워보는 Vue.js, ES6, Vuex 강의를 토대로 작성하였습니다.
1. Modal Component
- Transition 효과
- text/x-template로 구현
- 템플릿을 모듈화
2. Modal Component 모듈화
- 프로젝트 전반에서 모달을 사용할 수 있도록 모듈화
- 재사용성
- 일반적으로 자주 사용하는 모듈은 src/components/common과 같은 경로에 정리
예시
<!-- src/components/common -->
<template>
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
default header
</slot>
</div>
<div class="modal-body">
<slot name="body">
default body
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
default footer
<button class="modal-default-button" @click="$emit('close')">
OK
</button>
</slot>
</div>
</div>
</div>
</div>
</transition>
</template>
<style>
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: table;
transition: opacity 0.3s ease;
}
.modal-wrapper {
display: table-cell;
vertical-align: middle;
}
.modal-container {
width: 300px;
margin: 0px auto;
padding: 20px 30px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
transition: all 0.3s ease;
font-family: Helvetica, Arial, sans-serif;
}
.modal-header h3 {
margin-top: 0;
color: #42b983;
}
.modal-body {
margin: 20px 0;
}
.modal-default-button {
float: right;
}
.modal-enter {
opacity: 0;
}
.modal-leave-active {
opacity: 0;
}
.modal-enter .modal-container,
.modal-leave-active .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
</style>
3. Slot
- 한 컴포넌트에서 모듈을 불러왔을 때 slot 부분을 재정의할 수 있음
- 일부 UI를 재사용
- 각 컴포넌트별로 불러온 모듈의 slot을 재정의하여 사용할 수 있음
예시
<template>
<div class="inputBox shadow">
<input type="text" v-model="newTodoItem" v-on:keyup.enter="addTodo">
<span class="addContainer">
<i class="fas fa-plus addBtn" v-on:click="addTodo"></i>
</span>
<!-- Modal 적용 -->
<Modal v-if="showModal" @close="showModal = false">
<!-- slot 재정의 -->
<h3 slot="header">
경고!
<i class="closeModalBtn fas fa-times" @click="showModal = false"></i>
</h3>
<span slot="body">아무것도 입력하지 않으셨습니다.</span>
</Modal>
</div>
</template>
<script>
// 모달 모듈 가져오기
import Modal from './common/Modal.vue';
export default {
data: function() {
return {
newTodoItem: "",
// 모달의 노출 여부
showModal: false,
}
},
methods: {
addTodo: function() {
if (this.newTodoItem !== ''){
// 부모로 보냄
this.$emit('addToDoItem', this.newTodoItem);
this.clearInput();
} else {
// 모달 노출
this.showModal = true;
}
},
clearInput: function() {
this.newTodoItem = '';
}
},
components: {
Modal: Modal
},
}
</script>
<style scoped>
...
</style>
4. Transition
- Vue에서 제공
- Vue의 문법으로 컴포넌트에 효과를 넣을 수 있음
Transition Classes
- v-enter: 처음 이펙트 시작 상태
- v-enter-to: 시작되고 끝난 상태
- v-leave: 없어지기 시작하는 상태
- v-leave-to: 없어진 상태
- 이에 맞게 클래스 지정
- 일반적으로 v-enter와 v-leave-to를, v-enter-to와 v-leave를 같이 사용
문법
**<transition-group name="클래스명" tag="적용할 태그명">**
- name 속성에 list속성을 지정하면
- list-enter, list-enter-to, list-leave, list-leave-to 클래스가 생성
예시
<template>
<div>
<!-- 트랜지션 효과 -->
<transition-group name="list" tag="ul">
<li v-for="(todoItem, index) in propsdata" v-bind:key="todoItem.item" class="shadow">
<i class="checkBtn fas fa-check" v-bind:class="{checkBtnCompleted: todoItem.completed}" v-on:click="toggleComplete(todoItem, index)"></i>
<!-- 조건부 class, true인 경우 해당 class를 적용 -->
<span v-bind:class="{textCompleted: todoItem.completed}">{{ todoItem.item }}</span>
<span class="removeBtn" v-on:click="removeTodo(todoItem, index)">
<i class="fas fa-trash-alt"></i>
</span>
</li>
</transition-group>
</div>
</template>
<script>
export default {
// props 받아오기
props: ["propsdata"],
methods: {
removeTodo: function(todoItem, index) {
this.$emit('removeItem', todoItem, index);
},
toggleComplete: function(todoItem, index) {
this.$emit('toggleItem', todoItem, index);
}
}
}
</script>
<style scoped>
...
/* 리스트아이템 트랜지션 효과*/
.list-enter-active,
.list-leave-active {
transition: all 1s;
}
.list-enter, .list-leave-to /* .list-leave-active below version 2.1.8 */ {
opacity: 0;
transform: translateY(30px);
}
...
</style>
Reference
'programming study > Vue' 카테고리의 다른 글
Vue.js - Vuex 설치 및 등록, state & getters (0) | 2021.10.26 |
---|---|
Vue.js - Vuex, Flux & MVC (0) | 2021.10.23 |
Vue.js - 컨테이너와 프레젠터, v-bind, v-on, 안티패턴 (0) | 2021.10.16 |
Vue.js - 로컬스토리지, 스타일 바인딩 (0) | 2021.10.09 |
Vue.js - 컴포넌트 생성, 반응형 태그, scoped, v-model, v-on, v-for (0) | 2021.10.07 |