본문 바로가기

Study/Vue & Vuetify

Vue.js 배우기 기초이론 Lv.01

0. Setting

ㅡ1) 설치

 : Node.js (nodejs.org/ko/) : 이왕이면 왼쪽편의 확인된 버전으로

ㅡ2) 크롬 확장 프로그램 설정

 : Vue.js dev tools (chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)

ㅡ3) VSCode-Plug-in 설치 (추천) : VSCode로 학습

  • Vetur : vue를 쓰기 위해 필수 플러그인
  • Material Icon Theme : 아이콘 테마 플러그인
  • Night Owl : 화면 테마 플러그인
  • Live Server : 서버를 바로 돌릴 수 있는 플러그인
  • ESLint : 코드오류 잡아주는 플러그인
  • Prettier : 코드스타일을 정리해주는 플러그인
  • Auto Close Tag : 자동 끝태그 생성 플러그인
  • Atom Keymap

 

1. Vue란?

: MVVM 패턴의 뷰모델(ViewModel) 레이어에 해당하는 화면(View)단 라이브러리

# 호환성 정보 : ECMAScript 5 기능을 사용 -> ECMAScript 5 호환 브라우저 지원

# CDN : <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

 

2. 간단&기초 Vue 시작

1) Vue 인스턴스 - new Vue() : 인스턴스를 생성하면 기본적인 Root컴포넌트가 됨

# 컴포넌트 Component : 화면의 영역을 구분하여 개발할 수 있는 뷰의 기능으로, 재사용성이 올라가고 빠르게 화면제작 가능

 

2) Vue 속성분류

- el : 연결할 div 영역을 지정

- data : 데이터 값

- components : 컴포넌트 지정

- methods : 함수

- computed : 지정한 데이터 값(a)이 변할 때를 인식하며 a의 값을 기반으로 만들어진 b의 값을 사용할 때 사용

- watch : 지정한 데이터 값(a)이 변할 때를 인식하며 그에 따른 함수 등 다른 작용을 낼 때 사용

(computed와 watch 는 아래 5. 뷰의 템플릿 문법에서 추가설명)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <div id="app">
 
        <app-header></app-header>
        <app-content></app-content>
        <app-footer></app-footer>
 
    </div>
 
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        // 전역 컴포넌트 Vue.component('컴포넌트이름', 컴포넌트 이름)
        Vue.component('app-header', {
                template: '<h1>HEADER</h1>'
        });
 
        var appContent = {
            template: '<h2> Content </h2>',
        }
 
        // 뷰 인스턴스
        var vm = new Vue({
            // el : 연결할 div영역을 지정 (ex.id="app"인 구역: "#app")
            el : "#app",
            
            // data : 데이터 값
            data : {
                message : 'hi',
                memo : 'Hello',
            },
 
            // components : 지역 컴포넌트
            components: {
                // 컴포넌트이름 : 컴포넌트 내용
                // 표현방법1
                'app-content' : appContent,
                // 표현방법2
                'app-footer': {
                    template: '<footer>Footer</footer>'
                },
            },
 
            // methods : 함수
            methods: {
                logText() {
                    console.log(this.messageHi);
                }
            }
        });
 
    </script>
</body>
</html>
cs

 

3) 컴포넌트의 통신 방식

  - 상위 컴포넌트: <Root>

  - 하위 컴포넌트: <AppContent> , <AppContent2>

 

# 상위->하위 : 데이터를 내려줌/ 프롭스(Props) 속성 이용 // v-bind:프롭스속성명='상위컴포넌트 데이터명'

                                                                        // props: ['프롭스속성명']

# 하위->상위 : 이벤트를 올려줌/ 이벤트(Event) 발생으로 // v-on:발생이벤트명='상위컴포넌트 메소드명'

                                                                       // this.$emit('발생이벤트명');

# 뷰 인스턴스에서의 this는 data의 내부속성을 가리킴

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
 
    <div id="app">
 
        <!-- props - 상위>하위 데이터 전달-->
        <!-- v-bind:프롭스속성이름='상위 컴포넌트의 데이터이름' -->
        <app-content v-bind:propsdata='memo'></app-content>
 
        <!-- Event emit -->
        <!-- v-on: 하위 컴포넌트에서 발생한 이벤트 이름='상위 컴포넌트의 메서드 이름'-->
        <app-content2 v-on:event='logText'></app-content2>
 
        <!-- {{ }} 를 이용하면 data의 값을 가져와 쓸 수 있다. (이후내용추가)-->
        <h1>{{message}}</h1>
 
    </div>
 
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appContent = {
            template: '<h2> propsdata : {{ propsdata }} </h2>',
            // 프룹스 props - 상위>하위 데이터 전달 속성
            // props : '값이름'
            props: ['propsdata']
        }
        var appContent2 = {
            template: '<button v-on:click="eventName">이벤트발생</button>',
            methods: {
                eventName() {
                    this.$emit('event');
                }
            }
        }
 
        // 뷰 인스턴스
        var vm = new Vue({
            el: "#app",
 
            data: {
                message: 'hi',
                memo: 'Hello',
            },
 
            components: {
                'app-content': appContent,
                'app-content2': appContent2,
            },
 
            methods: {
                logText() {
                    console.log(this.memo);
                }
            }
        });
    </script>
</body>
 
</html>
cs

 

4) 상위 컴포넌트를 두고, 같은 레벨의 컴포넌트 간의 통신방법

: 동일하게 공유하는 상위 컴포넌트 단계까지 이벤트를 통해 값을 올리고 프롭스로 값을 내려받는다.

 

(예시) appContent2 에서 값을 App으로 보내면 App에서 data를 변경한다.(이벤트)

        -> App의 데이터 정보를 appContent에서 받아서 화면에 반영한다.(프룹스)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<div id="app">
    <!-- 이벤트를 받을 컴포넌트 -->
    <app-content v-bind:propsdata="message"></app-content>
    <!-- 이벤트를 실행하여 데이터를 보낼 컴포넌트 -->
    <app-content2 v-on:event='sendEvent'></app-content2>
</div>
 
 
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var appContent = {
        template: '<h1>{{ propsdata }}</h1>',
        props: ['propsdata']
    }
    var appContent2 = {
        template: '<div><button v-on:click="eventHi">Event발생</button></div>',
        methods: {
            eventHi() {
                //this.$emit('이벤트명', 보내는 값)
                this.$emit('event''이벤트 후');
            }
        }
    }
 
    new Vue({
        el: '#app',
        data: {
            message: '이벤트 전'
        },
        components: {
            'app-content': appContent,
            'app-content2': appContent2,
        },
        methods: {
            sendEvent(value) {
                this.message = value;
            }
        }
    })
 
</script>
    
</body>
</html>
cs

 

 

3. 뷰 라우터(Vue-Router)

: 뷰 라이브러리를 이용하여 페이지를 이동하는 싱글 페이지 애플리케이션을 구현할 때 사용하는 라이브러리

 

1) 라우터 사용순서

-1. 다운받거나 CDN 사용 (https://router.vuejs.org/installation.html#direct-download-cdn)

    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

-2. new VueRouter() 인스턴트 생성

-3. Vue의 router 속성에 위 생성자로 만들어진 라우터 지정

 

2) 라우터 사용

-1. vue 먼저, 다음에 router CDN 등록

-2. 뷰 인스턴스 생성

-3. 뷰 라우터 인스턴스 생성

-4. 뷰 인스턴스 내에 뷰 라우터 등록

 

* router-view 태그 & router-link 태그

ㅡrouter-view : url 변경 시, 앞에서 정의한 routes 속성에 따라 해당 컴포넌트가 화면에 뿌려지는데 이 영역을 의미

ㅡrouter-link : 화면에서 특정 링크를 클릭하여 페이지를 이동할 수있게 해주는 기능

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
    <div id="app">
 
        <div># Router-Link 영역 #</div>
        <router-link to="/one">PageOne</router-link>
        <router-link to="/two">PageTwo</router-link>
        
        <hr>
        
        <div># Router-View 영역 #</div>
        <router-view></router-view>
 
    </div>
 
    <!-- 1) vue 먼저, 다음에 router 등록 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
 
    <script>
        var pageOne = {
            template: '<h1>PAGE ONE</h1>'
        }
        var pageTwo = {
            template: '<h2>PAGE TWO</h2>'
        }
 
        // 3) 뷰 라우터 인스턴스 생성
        var router = new VueRouter({
            routes: [
                // PageOne페이지원 정보
                {
                    //url 이름
                    path: '/one',
                    name'pageOne',
                    component: pageOne,
                },
                // pageTow 페이지투 정보
                {
                    path: '/two',
                    name'pageTwo',
                    component: pageTwo,
                }
            ]
        })
 
        // 2) 뷰 인스턴스 생성
        new Vue({
            el: '#app',
            router,     // 4)라우터 등록
        })
 
    </script>
 
 
 
</body>
 
</html>
cs

 

4. 엑시오스(Axios)

: 뷰에서 권고하는 HTTP 통신 라이브러리 / Promise based HTTP client for the browser and node.js

(엑시오스 깃헙: https://github.com/axios/axios)

 

1) 엑시오스 사용순서

-1. CDN

<script src="https://unpkg.com/axios/dist/axios.min.js"></script> <!--엑시오스 CDN-->

-2. vue 인스턴스 내에서 method로 엑시오스 실행

<Axios 구성>

1
2
3
4
5
6
7
8
9
10
11
12
13
axios.get( 실행할 비동기처리 내용 )
 
      .then(function (response) { // response = 비동기처리 실행후 return 된 데이터
 
            성공시 실행될 내용
 
      })
 
      .catch(function (error) {
 
            실패시 실행될 내용
 
      });
cs

 

2) 엑시오스 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
    <div id="app">
        <button v-on:click="methodAxios">Click me: Get Data</button>
        <div>
            {{ users }}
        </div>
    </div>
 
    <!-- vue CDN + Axios CDN-->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
 
    <script>
        new Vue({
            el: '#app',
            data: {
                users: [] //가져온 데이터를 담을 리스트
            },
            methods: {
                methodAxios() {
                    var vm = this;
                    axios.get('https://jsonplaceholder.typicode.com/users/'//샘플데이터
                        .then((response) => {
                            //console.log(response);
                            vm.users = response;
                        })
                        .catch((error) => {
                            console.log(error);;
                        })
                }
            }
        })
 
    </script>
</body>
 
</html>
cs

 

 

5. 뷰의 템플릿 문법

: 뷰로 화면을 조작하는 방법을의미 / 데이터 바인딩 & 디렉티브로 나뉨

 

a. 데이터 바인딩 : 뷰 인스턴스에서 정의한 속성들을 화면에 표시하는 방법 //

                       콧수염괄호(머스태치 태그 Mustache Tag) - {{ message }}

 

b. 디렉티브 : 뷰로 화면의요소를 더 쉽게 조작하기 위한 문법 (v-)

 

# computed vs watch

computed : 데이터 값을 계산할 때 주로 사용

watch : 뷰 내의 값이 바뀔 때를 인식하여 함수를 실행시킴

# 공식문서에선, Computed vs Watched Property에 대해

: However, it is often a better idea to use a computed property rather than an imperative watch callback.

= watch 보다 computed 속성 사용을 권고

 

1) 디렉티브 몇가지 사용법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!--
            v-bind:id="id명" : id 지정
            v-bind:class="class명" : class 지정
                        ="{ class명 : true/false }" 값에따른 설정 가능
        -->
        <p v-bind:id="uid" v-bind:class="cname"> num : {{ num }}</p>
        <p v-bind:class="{ warning : flag }"> double : {{ double }}</p>
        <!--
            v-on:click="method명" : 클릭을 통해 메소드 실행
        -->
        <button v-on:click="changeFlag">색 바꾸기</button>
        <!--
            v-if="true/false" , v-else : if값에 따라 실행부분이 나뉨
        -->
        <div v-if="flag">
            flag true..
        </div>
        <div v-else>
            flag false..
        </div>
        <!--
            v-show="true/false" : 값에 따라 보여줄지 말지 선택가능
        -->
        <div v-show="flag">
            flag ture!!
        </div>
        <hr>
 
        ## 텍스트 입력하기 ## <br>
        <input type="text" v-model="message" placeholder="입력" />
        <p>Message is = {{ message }}</p>
        <hr>
 
        ## 값 바꾸기 ## <br>
        <input type="number" v-model="num" placeholder="숫자입력" />
        <button v-on:click="addNum">Plus One</button>
        <p> num : {{ num }}</p>
        <p> text : {{ text }}</p>
        <button v-on:click="clear">Clear Text</button>
 
 
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                uid: 'abcd',
                cname: 'back-blue',
                flag: true,
                message: '',
                num: 10,
                text: '',
            },
            computed: { // data값을 계산할 때 사용
                double() {
                    return this.num * 2;
                },
                errorText() {
                    return this.flag ? 'warning' : null;
                }
            },
            watch: { // 뷰 내의 값이 바뀔 때를 인식하여 함수를 실행시킴
                num() {
                    this.logText();
                }
            },
            methods: {
                addNum() {
                    this.num++;
                },
                logText() {
                    this.text += '값 변경! '
                },
                changeFlag() {
                    this.flag = !this.flag;
                },
                clear() {
                    this.num=10;
                    this.text='';
                    this.message='';
                }
            }
 
        })
    </script>
 
    <style>
        .back-blue {
            background-color: blue;
        }
        #abcd {
            color: white;
        }
        .warning {
            color: red;
        }
    </style>
</body>
</html>
cs

 

 

<Vue_Study_Lv1.> : github.com/sogno12/Vue_Study_lv1.git