02월02일(목) Vue CLI

하이·2023년 2월 3일
0

수업

목록 보기
19/41
post-custom-banner

기존방식
: HTML 파일내에 JavaScript code를 포함하고 component를 생성할 때 template 속성을 이용함
=> 사용하기 불편, 유지보수가 힘들다

=> 그래서, Single File Component 사용
: component 1개가 File 1개로 구현
: ~~.vue 라는 확장자 이용

.vue file의 구조

<template>
 : component의 template속성에 들어있던 HTML 내용
</template>

<scirpt>
	export default {
    : 객체를 표현하는.. data, methods, props, created, computed...
    : JavaScript객체가 module화
    : 다른 JavaScript file에서 이 객체를 사용하려면 export/import 과정이 필요함
    : 객체를 외부로 노출시키는 과정
    }
</scirpt>

<style>
	: 위에 있는 HTML 부분에 대한 CSS
</style>

: .vuefile을 browser가 해석이 불가능한 file
: 이 문제를 해결하기 위해 module bundler를 이용
: HTML, CSS, JavaScript를 1개의 file로 생성
: webpack(웹팩) 설치-설정-사용해야함
: browserify(브라우져리파이)
=> 너무 복잡해서 Vue core 개발 team
: Vue CLI
: node.js의 module로 제공
그래서 node.js를 이용해서 일단 Vue CLI를 설치해야함

Vue CLI

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>

간단한 To-do app을 만들어보자

(화면을 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>

여기까지는 모두 삭제 후 새로고침해야 화면에서도 사라짐

=> 반응성을 넣어보자

profile
기록의 즐거움 😆💻
post-custom-banner

0개의 댓글