9 템플릿 문법 - 기본

source: categories/study/vue-beginner-lv1/vue-beginner9-00.md

9.1 템플릿 문법 소개

Vue로 화면을 조정할 때 쓰는 속성과 기능에 대해서 알아보도록 하겠습니다.

Vue의 템플릿 문법이란 Vue로 화면을 조작하는 방법을 의미합니다.

템플릿 문법은 크게 데이터 바인딩과 디렉티브, 이렇게 2가지로 나뉩니다.

데이터 바인딩은 위와 같이 콧수염 괄호(Mustache Tag) 같은 것을 사용해 data나 앞으로 배우시게될 computed 혹은 기타 속성들을 화면에 나타내는걸 말합니다.

위와 같이 'Hello Vue.js' 같은 stringmessage 속성에 담아놓고 화면과 연결할 때 사용하는 것이 바로 Mustache Tag입니다.

두번째로 보실거는 바로 Directive인데, DirectiveHTML 태그에서 id라던지 class라던지, 이런 표준 속성을 제외하고 v-이렇게 시작하는 속성들을 모두 Vue Directive라고 하고 있습니다.

v-로 시작하는 속성들은 Vue에서 인식해서 내부적으로 조작을 합니다.

  • Data Binding
  • Vue Directive

9.2 데이터 바인딩과 computed 속성

템플릿 문법에 대해 알아보도록 하겠습니다.

첫번째로 보실 부분은 데이터 바인딩입니다.

playground/data-binding.html 파일을 만듭니다.

이 다음 시간부턴 vue-cli를 배우게됩니다.

그럼 위와 같이 매번 html 파일을 생성하고 태그들을 입력할 필요 없이 명령어로 바로 작업을 시작할 수 있는 서버라던지 파일 체계를 구성할 수 있게됩니다.



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue data-binding</title>
</head>
<body>
<div id="app">{{ str }}</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        str: 'hi'
    }
})
</script>
</body>
</html>


위와 같이 값이 변경되었을 때, 화면에 바로 반영되는 것을 reactivity라고 말씀드렸었고, 실제로 object define property로 그런걸 구현했을 때, 위와 같이 값이 연결되는 구간이 data binding이라고 보시면 될 거 같습니다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue data-binding</title>
</head>
<body>
<div id="app">
    <p>{{ num }}</p>
    <p>{{ doubleNum }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        num: 10,
    },
    computed: {
        doubleNum: function () {
            return this.num * 2;
        },
    }
})
</script>
</body>
</html>

num 값을 바꾸면 num 값에 computed 속성으로 연관되어있는 doubleNum 속성도 바뀐다.

computed 속성이 어떤 부분에서 더 의미가 있는지 다음 시간에 알아보도록 하겠습니다.

computed는 클래스 바인딩, 스타일 바인딩까지 같이 묶어서 얘기를 해보도록 하겠습니다.

바로 다음 시간은 아니고 클래스 바인딩, 스타일 바인딩에 대해 말씀드리고난 다음에 그 다음에 같이 살펴보도록 하겠습니다.

9.3 실습 안내 - 뷰 디렉티브(v-)와 v-bind

앞에서 살펴봤던 data binding에 이어서 이번 시간엔 뷰 디렉티브에 대해서 알아보도록 하겠습니다.

뷰 디렉티브는 v-가 붙는 특수한 속성들을 의미합니다.

이러한 특수한 속성들을 활용해 어떠한 것을 할 수 있는지 살펴보도록 하겠습니다.

만약 첫번째 p 태그에 id를 위와 같이 부여하고 싶다고 해보죠.

abc1234Vue 내부 어떤 로직에 의해 나왔다고 해보겠습니다.

그랬을 때 저 iddata로 관리를 하고 싶을거 같아요.

그랬을 때 위와 같이 uuid라는 속성에 'abc1234' 값을 넣을 수 있을 거 같아요.

그러면 저희가 원하는 값이 uuid라는 data 속성으로 관리가되고있죠?

그래서 uuid를 화면의 특정 태그의 id로 연결하시려면

여기서 사용하실 수 있는 것이 v-bind라는 것이 있습니다.

bind라는 의미 그대로 데이터를 bind하겠다는 거고


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
    <title>Vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid">{{num}}</p>
    <p>{{doubleNum}}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            // 아래 num 값이 바뀌면
            num: 10,
            uuid: 'abc1234',
        },
        computed: {
            doubleNum: function () {
                // data의 num 속성과 관련있는 이 doubleNum 값도 같이 바뀝니다.
                // 이 computed라는 속성이 어떤 부분에서 더 의미가 있는지 알아보도록 하겠습니다. (클래스 바인딩, 스타일 바인딩까지 묶어서 살펴보도록 하겠습니다.)
                return this.num * 2;
            }
        }
    })
</script>
</body>
</html>

위와 같이 id 속성에 uuid를 연결하겠다 라고 정의하시면됩니다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid">{{ num }}</p>
    <p>{{ doubleNum }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        num: 10,
        uuid: 'abc1234',
    },
    computed: {
        doubleNum: function () {
            return this.num * 2;
        },
    }
})
</script>
</body>
</html>

v-bindhtml 표준 속성(id, class..) 앞에 붙게되면 data에서 관리하는 특정 속성값과 연결된다라고 보시면 됩니다.

위와 같이 abc1234id 값으로 들어간 것을 볼 수 있고, 이 abc1234data에서 관리되고 있음도 알 수 있습니다.

위와 같이 uuid 값을 eee123이라고 바꿔보겠습니다.

여기서 저희가 알 수 있는 것은 단지 화면에서 표현되는 텍스트값 뿐만아니라 전체적인 DOM에 대한 정보들까지 reactivity하게 바로바로 다시 반영해서 DOM을 변경해준다라는 것이 바로 Vue에서 하는 역할이라고 보시면 됩니다.

예전엔 이런것들을 querySelector 같은 걸로 일일히 쫓아가서 그 안에 내용들을 일일이 바꿔주는 코드를 넣었어야했는데, 이제는 v-bind와 같은 문법을 이용해서 저희가 편하게 데이터만 조작해도 값이 바뀌는 것을 경험할 수 있는 것이죠.

클래스이름도 위와 같이 id처럼 연동되게 만들어보세요.

위와 같이 text-blue라는 문자열을 name이란 속성으로 가지고 있습니다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
    <title>Vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid" v-bind:class="name">{{num}}</p>
    <p>{{doubleNum}}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            // 아래 num 값이 바뀌면
            num: 10,
            uuid: 'abc1234',
            name: 'text-blue'
        },
        computed: {
            doubleNum: function () {
                // data의 num 속성과 관련있는 이 doubleNum 값도 같이 바뀝니다.
                // 이 computed라는 속성이 어떤 부분에서 더 의미가 있는지 알아보도록 하겠습니다. (클래스 바인딩, 스타일 바인딩까지 묶어서 살펴보도록 하겠습니다.)
                return this.num * 2;
            }
        }
    })
</script>
</body>
</html>

그때 위와 같이 v-bindclass로 그 값을 연결해보세요.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid" v-bind:class="name">{{ num }}</p>
    <p>{{ doubleNum }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        num: 10,
        uuid: 'abc1234',
        name: 'text-blue',
    },
    computed: {
        doubleNum: function () {
            return this.num * 2;
        },
    }
})
</script>
</body>
</html>

9.4 실습 풀이 - 클래스 바인딩, v-if, v-show

앞에서 말씀드린 classname 연결하는거 바로 진행해보도록 하겠습니다.

id 연결한 코드 참고하시면 쉽게 연결하실 수 있습니다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid" v-bind:class="name">{{ num }}</p>
    <p>{{ doubleNum }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        // 아래 num 값이 바뀌면
        num: 10,
        uuid: 'abc1234',
        name: 'text-blue',
    },
    computed: {
        doubleNum: function () {
            // data의 num 속성과 관련있는 이 doubleNum 값도 같이 바뀝니다.
            // 이 computed라는 속성이 어떤 부분에서 더 의미가 있는지 알아보도록 하겠습니다. (클래스 바인딩, 스타일 바인딩까지 묶어서 살펴보도록 하겠습니다.)
            return this.num * 2;
        },
    }
})
</script>
</body>
</html>


v-if

위와 같이 v-bind 말고도 유용한 뷰 디렉티브가 있는데, 해당 디렉티브까지 바로 확인해보도록 하겠습니다.

위쪽의 div는 user가 로그인되기 전에 로딩 상태를 의미하는 것이고,

아래는 user가 로그인하고나면 실제로 로그인되었습니다 라고하는 상태표시를 나타내는 div 태그입니다.

로딩중이면 Loading… 텍스트가 표시가되게하고 로그인이 끝났으면 그 아래에있는 것이 표시가되도록 v directive로 구현을 해보겠습니다.

위와 같이 v-if 속성을 활용해보도록 하겠습니다.

v directive 속성이 붙는순간 datacomputed 속성을 뒤질거라고 말씀을 드렸었죠?

위와 같이 dataloading이라는 속성을 정의해주시고, 불린 값을 넣습니다.

일단 true를 넣어놓겠습니다.

위와 같이 아래 태그에는 v-else 속성을 넣습니다.

loading이라는 data의 속성값이 truev-else가 선언된 태그는 화면에 표시안되겠죠?

그런데 loading이 만약 falsev-else가 선언된 태그가 화면에 나올것입니다.

전형적인 프로그래밍상에서 if-else를 생각하시면됩니다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
    <title>Vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid" v-bind:class="name">{{num}}</p>
    <p>{{doubleNum}}</p>
    <!-- 아래와 같이 v-if 속성을 활용해보도록 하겠습니다. -->
    <!-- 이런 v directive 속성이 붙는순간 data나 computed 속성을 뒤질거라고 말씀드렸었죠? -->
    <div v-if="loading">
        Loading...
    </div>
    <div v-else>
        test user has been logged in
    </div>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            // 아래 num 값이 바뀌면
            num: 10,
            uuid: 'abc1234',
            name: 'text-blue',
            // 이렇게 data에 loading이란 속성을 정의해주시고, 불린 값을 넣습니다.
            loading: true,
        },
        computed: {
            doubleNum: function () {
                // data의 num 속성과 관련있는 이 doubleNum 값도 같이 바뀝니다.
                // 이 computed라는 속성이 어떤 부분에서 더 의미가 있는지 알아보도록 하겠습니다. (클래스 바인딩, 스타일 바인딩까지 묶어서 살펴보도록 하겠습니다.)
                return this.num * 2;
            }
        }
    })
</script>
</body>
</html>


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid" v-bind:class="name">{{ num }}</p>
    <p>{{ doubleNum }}</p>
    <div v-if="loading">
        Loading...
    </div>
    <div v-else>
        test user has been logged in
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        num: 10,
        uuid: 'abc1234',
        name: 'text-blue',
        loading: true,
    },
    computed: {
        doubleNum: function () {
            return this.num * 2;
        },
    }
})
</script>
</body>
</html>

위와 같이 false로 바꾸면 v-else 표시가된 태그가 나옵니다.

이런식으로 v-if를 활용하면 좋을 거 같고, 조건에따라서 특정 태그의 내용을 보여주느냐 안보여주느냐에 대해 위와 같이 정의하시면 됩니다.


v-show


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid" v-bind:class="name">{{ num }}</p>
    <p>{{ doubleNum }}</p>
    <div v-if="loading">
        Loading...
    </div>
    <div v-else>
        test user has been logged in
    </div>
    <div v-show="loading">
        Loading...
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        num: 10,
        uuid: 'abc1234',
        name: 'text-blue',
        loading: true,
    },
    computed: {
        doubleNum: function () {
            return this.num * 2;
        },
    }
})
</script>
</body>
</html>

이번엔 v-show라는 속성을 활용해보겠습니다.

그랬을 때 ifshow의 차이점이 뭔지 화면에서 확인해보겠습니다.

loadingtrue인 상태에선 둘이 동일하게 보여지고 있습니다.

그때 위와 같이 체크를 풀고 요소검사를 해보면,

p태그와 div 태그 사이에 v-if 속성이 선언된 div 태그가 있죠?

v-ifDOM을 아예 제거해버립니다.

v-show는 위와 같이 보시는 것처럼 CSS styledisplay: none으로 육안상으로만 보이지않게하고 DOM의 정보는 남깁니다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
    <title>Vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid" v-bind:class="name">{{num}}</p>
    <p>{{doubleNum}}</p>
    <!-- 아래와 같이 v-if 속성을 활용해보도록 하겠습니다. -->
    <!-- 이런 v directive 속성이 붙는순간 data나 computed 속성을 뒤질거라고 말씀드렸었죠? -->
    <div v-if="loading">
        Loading...
    </div>
    <div v-else>
        test user has been logged in
    </div>
    <!-- v-if와 v-show의 차이점: loading이 true일 때는 동일하게 보여집니다. -->
    <!-- 하지만 loading이 false일 때는 v-show는 해당 요소를 display: none으로 만들지만 v-if는 해당 요소를 DOM에서 아예 제거해버립니다. -->
    <div v-show="loading">
        Loading...
    </div>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            // 아래 num 값이 바뀌면
            num: 10,
            uuid: 'abc1234',
            name: 'text-blue',
            // 이렇게 data에 loading이란 속성을 정의해주시고, 불린 값을 넣습니다.
            loading: true,
        },
        computed: {
            doubleNum: function () {
                // data의 num 속성과 관련있는 이 doubleNum 값도 같이 바뀝니다.
                // 이 computed라는 속성이 어떤 부분에서 더 의미가 있는지 알아보도록 하겠습니다. (클래스 바인딩, 스타일 바인딩까지 묶어서 살펴보도록 하겠습니다.)
                return this.num * 2;
            }
        }
    })
</script>
</body>
</html>

이런 미세한 차이점까지 인지하신 상태에서 서비스를 구현하시면 조금 더 도움이되실 거 같습니다.

실은 이러한 문법들을 맨 마지막에 다루는 이유가 있습니다.

구현하실 때는 이런 API를 직접 찾아서 구현하셔야됩니다. 그 방법에 대해서도 다음시간에 알아보도록 하겠습니다.

이 다음시간에 실제로 공식문서를 찾아가면서 어떤 것을 해보겠습니다.

  1. 필요한 API에 대해 찾는 방법
  2. 그리고 그걸 찾아서 구현하는 방법

9.5 모르는 문법이 나왔을 때 공식 문서를 보고 해결하는 방법

앞시간에 말씀드린 것처럼 이번 시간엔 제가 일방적으로 지식을 전달하는 것이 아니라 직접 개발하는 사람의 입장이 되어서 위의 기능을 구현해볼겁니다.


내가 구현한 답


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid" v-bind:class="name">{{ num }}</p>
    <p>{{ doubleNum }}</p>
    <div v-if="loading">
        Loading...
    </div>
    <div v-else>
        test user has been logged in
    </div>
    <div v-show="loading">
        Loading...
    </div>
    <!-- TODO: 인풋 박스를 만들고 입력된 값을 p 태그에 출력해보세요 -->
    <input type="text" v-on:change="inputChange">
    <p>{{ inputText }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        num: 10,
        uuid: 'abc1234',
        name: 'text-blue',
        loading: true,
        inputText: null,
    },
    computed: {
        doubleNum: function () {
            return this.num * 2;
        },
    },
    methods: {
        inputChange: function (e) {
            this.inputText = e.target.value;
        }
    }
})
</script>
</body>
</html>

위와 같이하면 단점이 input에 입력할 때마다 바로바로 반영되는 것이 아니라 input에 입력하고 다른델 클릭하거나 엔터를 쳐야 화면에 반영됩니다.


서비스를 구현하는데 필요한 모든 기능과 지식은 뷰에 다 내장되어있습니다.

위와 같이 바로 방법이 나와있습니다.

이것이 문서화가 잘된 라이브러리의 장점입니다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid" v-bind:class="name">{{ num }}</p>
    <p>{{ doubleNum }}</p>
    <div v-if="loading">
        Loading...
    </div>
    <div v-else>
        test user has been logged in
    </div>
    <div v-show="loading">
        Loading...
    </div>
    <!-- TODO: 인풋 박스를 만들고 입력된 값을 p 태그에 출력해보세요 -->
    <input type="text" v-model="message">
    <p>{{ message }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        num: 10,
        uuid: 'abc1234',
        name: 'text-blue',
        loading: true,
        message: '',
    },
    computed: {
        doubleNum: function () {
            return this.num * 2;
        },
    },
})
</script>
</body>
</html>


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
    <title>Vue data-binding</title>
</head>
<body>
<div id="app">
    <p v-bind:id="uuid" v-bind:class="name">{{num}}</p>
    <p>{{doubleNum}}</p>
    <!-- 아래와 같이 v-if 속성을 활용해보도록 하겠습니다. -->
    <!-- 이런 v directive 속성이 붙는순간 data나 computed 속성을 뒤질거라고 말씀드렸었죠? -->
    <div v-if="loading">
        Loading...
    </div>
    <div v-else>
        test user has been logged in
    </div>
    <!-- v-if와 v-show의 차이점: loading이 true일 때는 동일하게 보여집니다. -->
    <!-- 하지만 loading이 false일 때는 v-show는 해당 요소를 display: none으로 만들지만 v-if는 해당 요소를 DOM에서 아예 제거해버립니다. -->
    <div v-show="loading">
        Loading...
    </div>
    <!-- TODO: 인풋 박스를 만들고 입력된 값을 p 태그에 출력해보세요 -->
    <!-- 아래와 같이하면 input에서 마우스 focus가 해제돼야지만 p태그에 값이 반영된다. -->
    <!-- <input type="text" v-on:change="inputValue"> -->
    <input type="text" v-model="message">
    <p>{{message}}</p>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            // 아래 num 값이 바뀌면
            num: 10,
            uuid: 'abc1234',
            name: 'text-blue',
            // 이렇게 data에 loading이란 속성을 정의해주시고, 불린 값을 넣습니다.
            loading: true,
            // 인풋 박스 만들고 입력된 값을 p 태그에 출력할 때 그냥 data의 프로퍼티를 input의 v-model에 넣으면된다.
            // inputValue: null,
            message: '',
        },
        computed: {
            doubleNum: function () {
                // data의 num 속성과 관련있는 이 doubleNum 값도 같이 바뀝니다.
                // 이 computed라는 속성이 어떤 부분에서 더 의미가 있는지 알아보도록 하겠습니다. (클래스 바인딩, 스타일 바인딩까지 묶어서 살펴보도록 하겠습니다.)
                return this.num * 2;
            }
        },
        // 인풋 박스 만들고 입력된 값을 p 태그에 출력할 때 아래와 같이 methods를 쓸 필요도 없다. v-model로 바로 data와 연동하면된다.
        // methods: {
        //     inputValue: function (e) {
        //         this.inputTxt = e.target.value;
        //     }
        // }
    })
</script>
</body>
</html>

위와 같이 콧수염 괄호(Mustache Tag)를 통해 data binding을 하고 해보면 아까와 다르게 v-model을 활용하니까 input에 입력하는 그즉시 바로바로 화면에 반영이됩니다.

최대한 검색을 많이 활용하시고,

Learn에서 Guide랑 API. 이런 것들을 보시면 좋을 거 같습니다.

9.6 methods 속성과 v-on 디렉티브를 이용한 키보드, 마우스 이벤트 처리 방법

이번 시간엔 method이벤트 헨들링에 대해 알아보도록 하겠습니다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>methods</title>
</head>
<body>
<div id="app">
    <button v-on:click="">Click me</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    methods: {
        
    }
})
</script>
</body>
</html>

method가 아닌 methods입니다.

왜냐하면 비즈니스 로직들은 일반적으로 1개가 아니라 여러개입니다.

그렇기 때문에 methods입니다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
    <title>method event handling</title>
</head>
<body>
<div id="app">
    <button v-on:click="logText">Click me</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        methods: {
            logText: function () {
                console.log('clicked');
            }
        }
    })
</script>
</body>
</html>


Event Modifier


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
    <title>method event handling</title>
</head>
<body>
<div id="app">
    <button v-on:click="logText">Click me</button>
    <input type="text" v-on:keyup="logText">
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        methods: {
            logText: function () {
                console.log('clicked');
            }
        }
    })
</script>
</body>
</html>

위와 같이 enter 키를 쳤을 때만 logText를 실행하겠다 라고 정의할 수도 있습니다.

이것을 event modifier이라고 부릅니다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
    <title>method event handling</title>
</head>
<body>
<div id="app">
    <button v-on:click="logText">Click me</button>
    <!-- event modifier, enter 키를 keyup할 때만 logText를 실행하겠다. -->
    <input type="text" v-on:keyup.enter="logText">
    <!-- event modifier, enter 키를 keyup할 때만 logText를 실행하겠다. -->
    <input type="text" v-on:keypress.enter="logText">
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        methods: {
            logText: function () {
                console.log('clicked');
            }
        }
    })
</script>
</body>
</html>


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>methods</title>
</head>
<body>
<div id="app">
    <button type="button" v-on:click="logText">Click me</button>
    <input type="text" v-on:keypress.enter="logText">
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
    el: '#app',
    methods: {
        logText: function () {
            console.log('clicked');
        },
    }
})
</script>
</body>
</html>

위와 같이 코드를 정의하면 keypress 이벤트에서 enter 키를 입력하였을 때만 logText 메소드를 실행한다는 의미입니다.

chapter9_6 clip thumbnail

enter 키를 제외한 다른 키를 입력할 때는 반응이 없다가 enter 키를 입력하면 logText 메소드를 실행합니다.

위와 같이 enter 키를 입력했을 때 메소드가 실행되도록 하는 방법도 알아두면 좋습니다.

위와 같이 input 창에 내용을 입력하고 enter 키를 입력하면 메소드가 실행되도록,

그리고 마우스로 add 버튼을 클릭해도 메소드가 실행되도록 하면,

마우스와 키보드 모두를 통해 이벤트를 제어할 수 있게할 수 있습니다.

이렇게하면 사용자 경험이 보다 더 좋아질 것입니다.

v-on은 이렇게 키보드 또는 마우스 이벤트를 받을 수 있는 뷰 디렉티브입니다.

그리고 마지막으로 .enter 같은 걸 이용해서 해당 이벤트에 대한 Modifier까지 할 수 있다 라고 알아두시면 됩니다.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=no">
    <title>method event handling</title>
</head>
<body>
<div id="app">
    <button v-on:click="logText">Click me</button>
    <!-- event modifier, enter 키를 keyup할 때만 logText를 실행하겠다. -->
    <input type="text" v-on:keyup.enter="logText">
    <!-- event modifier, enter 키를 keyup할 때만 logText를 실행하겠다. -->
    <input type="text" v-on:keypress.enter="logText">

    <!-- 여튼 이런식으로 input 창에 내용을 입력하고 enter키를 입력하면 메소드가 실행되도록 -->
    <!-- 그리고 마우스로 add 버튼을 클릭해도 메소드가 실행되도록하면 -->
    <!-- 마우스와 키보드 모두를 통해 이벤트를 제어할 수 있게할 수 있습니다. -->
    <!-- 이렇게하면 사용자 경험이 보다 더 좋아질 것입니다. -->

    <!-- v-on은 이렇게 마우스 또는 키보드 이벤트를 받을 수 있는 뷰 디렉티브입니다. -->
    <!-- 그리고 마지막으로 .enter 같은걸 이용해서 해당 이벤트에 대한 modifier까지 할 수 있다 라고 알아두시면됩니다. -->
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        methods: {
            logText: function () {
                console.log('clicked');
            }
        }
    })
</script>
</body>
</html>