반응형



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
<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
    </head>
    <body>
        <div id = "app" >
            <!-- button v-on:click ="counter += 1"></button> -->
            <button @click="func()"> Add </button>
            <p> click cnt :: {{counter}} </p>
        </div>
 
        <script>
            var vm = new Vue({
                el : '#app',
                data:{
                    counter : 0
                },
                methods:{
                    func: function(){
                        // this.$data.counter += 1
                        this.counter += 1;
                    }
                }
 
            })
 
        </script>
    </body>
</html>
cs


v-on:click를 이용하여 button이든 div든 다양한 곳에 이벤트를 삽입 할 수 있다.


v-on을 @으로 대체 할 수 있으며 @click="함수명"를 이용하면 된다.


다양한 곳에 쓰이게 되는 이벤트이니 v-on / @ 디렉티브를 잘 이해하고 있자.



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
<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
    </head>
    <body>
        <div id = "app" >
            <button v-on="{ mousedown : doThis, mouseup : doThat }"> 객체로 이벤트 리스너 추가 </button>
            <p> {{ val }} </p>
        </div>
 
        <script>
            var vm = new Vue({
                el : '#app',
                data:{
                    val: 'none',
                },
 
                methods:{
                    doThis: function(){
                        this.val = "마우스 누름";
                    },
                    doThat: function(){
                        this.$data.val = "마우스 안 누름";
                    }
                }
                
            })
 
        </script>
    </body>
</html>
 
cs


v-on을 통해 mousedown과 mouseup이벤트를 이용할 수 있다.


이때 { }를 이용하여 하나의 문장에 2개의 이벤트를 삽입 할 수 있다.


물론 v-on:mousedown="doThis()" @mouseup = "doThat()"로도 사용이 가능하다.




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
<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
    </head>
    <body>
        <div id="app">
            <p> {{ message }} </p>
            <button @click="reverseMessage()"> 메시지 뒤집기 </button>
        </div>
 
        <script>
            var vm = new Vue({
                el : '#app',
                data:{
                    message : "안녕하세요",
                },
                methods:{
                    reverseMessage: function(){
                        this.message = this.message.split('').reverse().join('');
                    }
                }
            })
        </script>
    </body></html>
cs


마우스 클릭이 일어나면 reverseMessage 함수가 호출된다.


이전에 reverse하는 방법을 봤듯이 이 함수가 call되면 message.split('')로 분리해서 reverse로 뒤집고 join('')으로 합치면 된다.




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
<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
    </head>
    <body>
        <div id="app">
            <button @click="greet($event, 'bye')">Greet</button>
        </div>
 
        <script>
            var vm = new Vue({
                el : '#app',
                data:{
                    name : 'vue.js'
                },
                methods:{
                    greet : function(even, arg){
                        alert('Hello' + this.name + arg);
 
                        if(event){
                            alert(event.target.tagName);
                        }
                    }
                }
            })     
        </script>
    </body>
</html>
cs


메서드 리스너를 호출할 때 메서드 호출 인자가 1개 이상일 때는 반드시 $event라는 인자를 이용하여 이벤트 정보를 명시적으로 실행해야 한다.




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
<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
    </head>
    <body>
        <div id = "app">
            <div @click = "doTop" style="background-color: blue; width : 200px; height : 200px;">
                <div @click="doMiddle" style="background-color: red; width:100px; height:100px;">
                    <button @click="doLast"> 제출 </button>
                    <!-- <input type ="button" @click="doLast" value = "제출"> -->
                </div>
 
            </div>
        </div>
 
        <script>
            var app = new Vue({
                el : '#app',
                methods:{
                    doTop : function(){
                        console.log("첫번째 div");
                    },
                    doMiddle:function(){
                        console.log("두번째 div");
                    },
                    doLast:function(){
                        console.log("세번째 div");
                    }
                }
            })
          </script>
    </body>
</html>
cs


이벤트 버블링은 다음과 같이 일어난다.


하나의 div속에 여러 이벤트가 겹겹이 있을 경우에 버블링이 일어난다.


위의 경우에서는 가장 위에있는 div @click="doTop"만 호출되지만 doMiddle에서는 doMiddle이 호출되고나서 doTop이 또 호출된다.


마지막 doLast를 호출하면 doLast -> doMiddle -> doTop 순으로 호출된다.


의도하지 않은 버블링이라면 이벤트를 구성할 때 조심하도록 하자.




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
<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
    </head>
    <body>
        <div id = "app">
            <form @submit.prevent = "doPrevent" action="/doPrevent">
                <input type="submit" value ="Default Action Cancel">
            </form>
        </div>
 
        <script>
            var app = new Vue({
                el : '#app',
                methods:{
                    doPrevent : function(){
                        console.log("기본 동작 취소");
                    }
                }
            })
        </script>
    </body>
</html>
cs


자바스크립트에서 기본 동작을 막아주는 .prevent이다.


.privent를 이용하면 prevent에 걸려 console.log에 기본 동작 취소가 뜨는데 prevent를 지우면 action이 발동하게 된다.



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
<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
    </head>
    <body>
        <div id = "app">
            <div @click.capture="doTop" style="background-color: blue; width : 200px; height: 200px;">
                <div @click.capture = "doMiddle" style="background-color:red; width:100px; height:100px">
                    <button @click="doLast"> 제출 </button>
                </div>
            </div>
        </div>
 
        <script>
            var vm = new Vue({
                el: "#app",
 
                methods:{
                    doTop: function(){
                        console.log("첫번째");
                    },
                    doMiddle: function(){
                        console.log("두번째");
                    },
                    doLast: function(){
                        console.log("세번째");
                    }
                }
            })
        </script>
    </body>
</html>
cs


.capture을 이용하면 이벤트 버블링에서 우선순위 변경이 가능하다.


아까 전의 코드와 다르게 이제는 doLast부분을 클릭하면 세번째->두번째->첫번째가 순서대로 나타남을 알 수 있다.




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
<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
    </head>
    <body>
        <div id = "app">
            <div style = "background-color : red; width : 100px; height : 100px;" @click="doMiddle">
                <a href="http://www.crocus.co.kr" @click.prevent.stop="doThat">타임라인</a>
            </div>
        </div>
 
        <script>
            var app = new Vue({
                el : '#app',
                methods:{
                    doThat:function(){
                        console.log("이벤트가 발생했지만 stop이벤트 수식어로 이벤트 정지");
                    },
                    doMiddle: function(){
                        console.log("doMiddle 이벤트 발생");
                    }
                    
                }
            })
        </script>
    </body>
</html>
 
 
cs


prevent이후 stop을 이용하여 이벤트가 전파되지 않도록 할 수 있다.


직접 prevent와 stop를 지워가며 패턴 변화를 알아보자.




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
<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
    </head>
    <body>
        <div id = "app" style="background-color:red; width:400px; height:400px">
            <div @click="doLast">
                <div style="background-color: blue; width:200px; height:200px" @click.self="doMiddle">
                    <span @click="doThat"> span element </span>
                </div>
            </div>
        </div>
 
        <script>
            var vm = new Vue({
                el: "#app",
 
                methods:{
                    doThat: function(){
                        console.log("첫번째");
                    },
                    doMiddle: function(){
                        console.log("두번째");
                    },
                    doLast: function(){
                        console.log("세번째");
                    }
                }
            })
        </script>
    </body>
</html>
cs


실제 자신으로부터 출발하는 이벤트일때만 호출하는 .self이다.


doLast를 클릭하면 doMiddle이 self로 인해 자신으로 출발하지 않아 doMiddle 부분을 빼고 출력이 되고


doMiddle을 클릭하면 자신으로부터 출발하여 출력이 된다.






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
<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
    </head>
    <body>
        <div id="app" style="background:red; width:200px; height:200px" @click.self="doTop">
            <div style="background:blue; width:100px; height:100px" @click.once="doMiddle">
 
            </div>
        </div>
 
        <script>
            var vm = new Vue({
                el : '#app',
 
                methods:{
                    doTop: function(){
                        console.log("top click!");
                    },
 
                    doMiddle: function(){
                        console.log("middle click!");
                    }
                }
            })
        </script>
    </body>
</html>
 
cs


.once 이벤트 수식어를 이용하여 한번만 클릭되게 할 수 있다.


한번 클릭하면 그 이후로는 클릭이 안된다. 이 방법을 이용하여 중복 클릭을 막을 수 있다.







반응형