Develop/Vue

Vue 애플리케이션 만들기

김니은  2020. 1. 26. 21:43
반응형

프로젝트 초기 설정

 

반응형 웹 디자인 태그를 설정해봅시다.

반응형 웹 디자인은 하나의 웹 사이트로 다양한 기기에서 깨지지 않고 자연스럽게 레이아웃을 제공해줍니다.

 

//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에 있기 때문에 접근을 해야 화면에 갱신이 됩니다.

내용이 너무 길어져 다음 글에 이어서 작성하겠습니다.

반응형