기존방식
: HTML 파일내에 JavaScript code를 포함하고 component를 생성할 때 template 속성을 이용함
=> 사용하기 불편, 유지보수가 힘들다
=> 그래서, Single File Component 사용
: component 1개가 File 1개로 구현
: ~~.vue 라는 확장자 이용
<template>
: component의 template속성에 들어있던 HTML 내용
</template>
<scirpt>
export default {
: 객체를 표현하는.. data, methods, props, created, computed...
: JavaScript객체가 module화
: 다른 JavaScript file에서 이 객체를 사용하려면 export/import 과정이 필요함
: 객체를 외부로 노출시키는 과정
}
</scirpt>
<style>
: 위에 있는 HTML 부분에 대한 CSS
</style>
: .vue
file을 browser가 해석이 불가능한 file
: 이 문제를 해결하기 위해 module bundler
를 이용
: HTML, CSS, JavaScript를 1개의 file로 생성
: webpack(웹팩) 설치-설정-사용해야함
: browserify(브라우져리파이)
=> 너무 복잡해서 Vue core 개발 team
: Vue CLI
: node.js의 module로 제공
그래서 node.js를 이용해서 일단 Vue CLI를 설치해야함
① Node.js 설치
② npm
(node package manager라는 module)을 이용해 Vue CLI 설치
npm install vue-cli --loaction=global
③ vue 엔터 : (실행 돼야 함)
④ Vue CLI는 Project생성 시 6개의 option이 있음
vue init webpack-simple
: 프로젝트 생성
⑤ 필요한 라이브러리 다운로드
npm install
vsCode에 설치
Chrome에 설치
App.vue
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
(화면을 mobile기준, CSS는 제공)
index.html
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<!-- 반응형 웹 형태로 구현 -->
<!-- mobile 형태로 구현 : meta 설정이 필요함 -->
<!-- viewport 설정을 해야 함 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 웹 아이콘 사용을 위한 CDN : 가장 대표적인 fontawesome을 이용함 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
<!-- 기본적인 favicon 설정 -->
<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-todo</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
TodoHeader.vue
<template>
<h1> 환영합니다 </h1>
</template>
<script>
export default {
}
</script>
<style scoped>
h1 {
color: #2F3B52;
font-weight: 900; /* 텍스트 굵기 */
margin: 2.5rem 0 1.5rem
}
</style>
TodoInput.vue
<template>
<div>
<input type="text"
placeholder="할 일을 입력하세요"
v-model="newTodoItem"
v-on:keyup.enter="addTodo">
<span class="addContainer" v-on:click="addTodo">
<i class="addBtn fa fa-plus" aria-hidden="true"></i>
</span>
<!-- <button @click="addTodo">추가</button> 위의 <span></span>으로 버튼 변경-->
</div>
</template>
<script>
export default{
data(){
return{
newTodoItem : ''
}
},
methods: {
addTodo(){
// 현재 입력한 할 일 목록을 저장해야 함
// 지금 서버 프로그램에 연결을 할 수 없음
// 서버쪽 데이터베이스에 해당 정보를 저장할 수 없음
// 그래서 browser가 가지고 있는 저장 장소를 이용
// browser내부에 저장장소가 크게 2가지 있음
// Storage와 IndexedDB가 있음
// Storage를 사용해 보자
// Storage는 LocalStorage와 SessionStorage로 나뉨
// 가장 일반적인 LocalStorage를 이용해보자
// JavaScript를 이용해서 이 저장공간에 내가 원하는 데이터 저장 가능
// 데이터는 Map 형태로 저장 가능 (key,value의 쌍)
// localStorage에 데이터 저장하기
// localStorage.setItem('키값', '변수값');
if(this.newTodoItem !== ""){
localStorage.setItem(this.newTodoItem, this.newTodoItem);
// 이 키워드 사용하면 이 공간을 내가 이용할 수 있어!
// localStorage.setItem('키값','변수값')
this.newTodoItem="";
}
console.log('클릭클릭');
}
}
}
</script>
<style>
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>
TodoList.vue
<template>
<section>
<!-- <ul>
<li v-for="todoItem in todoItems">{{ todoItem }}</li>
</ul> -->
<ul>
<li v-for="(todoItem, index) in todoItems" :key="todoItem" class="shadow">
<i class="checkBtn fa fa-check" aria-hidden="true"></i>
{{ todoItem }}
<!-- @click은 v-on:click과 동일하게 동작합니다.
추가적으로 @click="[method1(), method2()]" 와 같이 사용하면
클릭이벤트를 여러개 설정할 수 있습니다.
-->
<!-- 삭제버튼 -->
<span
class="removeBtn"
type="button"
@click="removeTodo(todoItem, index)"
>
<i class="fa fa-trash" aria-hidden="true"></i>
</span>
</li>
</ul>
</section>
</template>
<script>
export default {
data() {
return {
todoItems: [],
};
},
methods : {
removeTodo(todoItem, index){
localStorage.removeItem(todoItem);
this.todoItems.splice(index,1);
}
},
created : function () {
// localStorage에서 데이터를 가져다가 todoItems에다 넣음
for(let i=0; i<localStorage.length; i++){
if(localStorage.key(i) !== 'loglevel:webpack-dev-server'){
// 데이터 넣기, key(i)로 key값을 가져옴. 몇번째 key값이냐
this.todoItems.push(localStorage.key(i))
}
}
},
}
</script>
<style scoped>
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>
TodoFooter.vue
<template>
<div class="clearAllContainer">
<span class="clearAllBtn" @click="clearTodo">모두 삭제</span>
</div>
</template>
<script>
export default {
methods: {
clearTodo(){
localStorage.clear();
}
}
}
</script>
<style scoped>
.clearAllContainer {
width: 8.5rem;
height: 50px;
line-height: 50px;
background-color: white;
border-radius: 5px;
margin: 0 auto;
}
.clearAllBtn {
color: #e20303;
display: block;
}
</style>
여기까지는 모두 삭제 후 새로고침해야 화면에서도 사라짐
=> 반응성을 넣어보자