Vue 애플리케이션 만들기
프로젝트 초기 설정
반응형 웹 디자인 태그를 설정해봅시다.
반응형 웹 디자인은 하나의 웹 사이트로 다양한 기기에서 깨지지 않고 자연스럽게 레이아웃을 제공해줍니다.
//index.html File
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>vue-kimn</title>
</head>
width=device-width 속성은 기기 너비만큼 웹 페이지의 너비를 지정하는 의미입니다.
아이콘과 폰트 파비콘 등 head 라인에서 추가할 수 있습니다.
저는 구그 폰트와 어썸 아이콘, 파비콘을 아래와 같이 추가하였습니다.
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="shortcut icon" href="src/assets/favicon.ico" type="image/x-icon">
<link rel="icon" href="src/assets/favicon.ico" type="image/x-icon">
<link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet">
<title>vue-kimn</title>
</head>
컴포넌트 생성
src 폴더 내의 components 폴더에 vue파일을 만들어줍니다.
저는 Header.vue, Input.vue, List.Vue, Footer.vue를 생성하였습니다.
컴포넌튼는 src/components 폴더에서 관리합니다.
또한 해당 폴더 내의 여러 폴더를 나눠 생성하여 관리할 수 있습니다.
ex) src/components/login, src/components/main 으로 나눠 vue파일을 관리할 수 있습니다.
컴포넌트 등록
위에 생성한 vue 파일을 등록해봅시다.
vue 파일들 각각 위와 같이 작성해줍시다.
그 후, 모두 최상위 컴포넌트인 app.vue를 수정하셔야 합니다.
<template>
<div id="app">
<Header></Header>
<Inputcheck></Inputcheck>
<List></List>
<Footer></Footer>
</div>
</template>
<script>
import Header from './components/Header.vue'
import Input from './components/Input.vue'
import List from './components/List.vue'
import Footer from './components/Footer.vue'
export default {
components: {
'Header': Header,
'Inputcheck': Input,
'List': List,
'Footer': Footer
}
}
</script>
<style>
</style>
먼저 해당 파일들을 Import 해줍니다.
그 후, components에 4개의 Vue 파일을 등록합니다.
등록한 후 Template부분에 표시하여 npm run dev를 입력해 화면 결과를 확인해봅시다.
최상위 컴포넌트 App 아래에 4개의 Vue 하위 컴포넌트가 생성된 것을 확인할 수 있습니다.
컴포넌트 구현하기
화면 출력이 제대로 되었다면 이제 구현해봅시다.
App.vue style
<style>
body {
text-align: center;
background-color: #F6F6F8;
}
input {
border-style: groove;
width: 200px;
}
button {
border-style: groove;
}
.shadow {
box-shadow: 5px 10px 10px rgba(0, 0, 0, 0.03)
}
</style>
배경화면과 텍스트 정렬방식, Input 박스 테두리모양, 아래 그림자를 정의하였습니다.
그럼 4개의 컴포넌트를 차례대로 수정해봅시다.
Header.Vue
<template>
<header>
<h2>Kimn Test</h2>
</header>
</template>
<script>
export default {
}
</script>
<style scoped>
h3 {
color: #2F3B52;
font-weight: 500;
margin: 2.5rem 0 1.5rem;
}
input {}
</style>
간단하게 style과 문구만 수정하였습니다.
Input.Vue
Input 박스와 버튼을 추가하는 단계입니다.
텍스트를 인식할 수 있도록 v-model 디렉티브를 이용하겠습니다.
<template>
<div>
<input type="text" v-model="newItem">
<button v-on:click="addItem">Insert</button>
</div>
</template>
<script>
export default {
data() {
return {
newItem: ''
}
},
methods: {
addItem() {
localStorage.setItem(this.newItem, this.newItem);
}
}
}
</script>
<style>
애플리케이션을 실행한 후 Vue 개발자도구를 열어봅시다.
글을 적은 후 App에 Inputcheck 확인해보시면 값이 갱신된 것을 확인할 수 있습니다.
또한 localStorage에 값이 저장되는지 확인해봅시다.
개발자 도구의 [Application - Local Storage] 에서 확인할 수 있습니다.
예외 처리 코드를 넣어봅시다.
입력된 텍스트가 없으면 데이터가 저장되지 않도록 예외처리를 추가해봅시다.
methods: {
addItem() {
if (this.newItem !== "") {
var value = this.newItem && this.newItem.trim();
localStorage.setItem(value, value);
this.clearInput();
}
},
clearInput() {
this.newItem = '';
}
}
if 조건을 통해 입력 값이 있을 경우 저장하도록 합니다.
trim 함수를 이용해 앞뒤 공백 문자열을 제거합니다.
그 후 clearInput() 함수를 짝하여 값을 초기화 시킵니다.
다음 아래는 css를 입힌 전체적인 Input 소스입니다.
<template>
<div class="inputBox shadow">
<input type="text" v-model="newItem" placeholder="Insert Text" v-on:keyup.enter="addItem">
<span class="addContainer" v-on:click="addItem">
<i class= "addBtn fa fa-plus" aria-hidden="true"></i>
</span>
</div>
</template>
<script>
export default {
data() {
return {
newItem: ''
}
},
methods: {
addItem() {
if (this.newItem !== "") {
var value = this.newItem && this.newItem.trim();
localStorage.setItem(value, value);
this.clearInput();
}
},
clearInput() {
this.newItem = '';
}
}
}
</script>
<style scoped>
input:focus {
outline: none;
}
.inputBox {
background: white;
height: 50px;
line-height: 50px;
border-radius: 5px;
}
.inputBox input {
border-style: none;
font-size: 0.9rem;
}
.addContainer {
float: right;
background: linear-gradient(to right, #6478FB, #8763FB);
display: inline-block;
width: 3rem;
border-radius: 0 5px 5px 0;
}
.addBtn {
color: white;
vertical-align: middle;
}
</style>
List.vue
로컬 스토리지에 저장된 내용을 화면에 출력해봅시다.
<template>
<section>
<ul>
<li v-for="ItemList in ItemLists" v-bind:key="ItemList">{{ ItemList }}</li>
</ul>
</section>
</template>
<script>
export default {
data() {
return {
ItemLists: []
}
},
created() {
if (localStorage.length > 0) {
for (var i = 0; i < localStorage.length; i++) {
this.ItemLists.push(localStorage.key(i));
}
}
},
}
</script>
<style>
</style>
created() 라이프 사이클 훅에 for 반복문과 push()로 로컬 스토리지의 모든 데이터를 로직에 추가합니다.
해당 데이터를 v-for 디렉티브로 구현합니다.
error: Elements in iteration expect to have 'v-bind:key' directives (vue/require-v-for-key) at
[vue/require-v-for-key]
위의 같은 에러는 Github 찾아보니 v-bind:key가 빠져서 생기는 에러였습니다.
이제 값 삭제 기능을 추가해봅시다.
<ul>
<li v-for="(ItemList, index) in ItemLists" v-bind:key="ItemList" class="shadow">
<i class="checkBtn fa fa-check" aria-hidden="true"></i>
{{ ItemList }}
<span class="removeBtn" type="button" @click="removeItem(ItemList, index)">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</span>
</li>
</ul>
...
methods: {
removeItem(ItemList, index) {
localStorage.removeItem(ItemList);
this.ItemLists.splice(index, 1);
}
},
...
<style>
ul {
list-style-type: none;
padding-left: 0px;
margin-top: 0;
text-align:left;
}
li {
display: flex;
min-height: 50px;
height: 50px;
line-height: 50px;
margin: 0.5rem 0;
padding: 0 0.9rem;
background: white;
border-radius: 5px;
}
.checkBtn {
line-height: 45px;
color: #62acde;
margin-right: 5px;
}
.removeBtn {
margin-left: auto;
color: #de4343;
}
</style>
style과 삭제 기능 methods를 추가하였습니다.
index와 Item 데이터를 이용하여 하나가 삭제된 것을 확인할 수 있었습니다.
Footer.vue
그럼 Footer에 모두 삭제하기 버튼을 넣어보겠습니다.
[Clear ALL] 버튼을 추가해봅시다!
<template>
<div class="clearAll">
<span class="clearBtn" @click="clearData">Clear All</span>
</div>
</template>
<script>
export default {
methods: {
clearData() {
localStorage.clear();
}
}
}
</script>
<style>
.clearAll {
width: 8.5rem;
height: 50px;
line-height: 50px;
background-color: white;
border-radius: 50x;
margin: 0 auto;
}
.clearBtn {
color: #e20303;
display: black;
}
</style>
로컬 스토리지 상에서는 데이터가 모두 삭제됬지만 화면에 갱신되진 않았습니다.
이는 목록 데이터는 List.vue에 있기 때문에 접근을 해야 화면에 갱신이 됩니다.
내용이 너무 길어져 다음 글에 이어서 작성하겠습니다.