본문 바로가기
front-end/Vue.js

Vue.js 이벤트

by 모두의 향연 2022. 7. 8.
728x90
반응형

✔️EVENT

: DOM Event를 청취하기 위해 v-on directive 사용

 

 

📌v-on

: v-on directive를 사용하여 DOM 이벤트를 듣고 트리거 될 때 JavaScript를 실행할 수 있다

<body>
  <div id="app">
    <button v-on:click="count++">클릭</button>
    <h2>클릭된 수는 {{count}}입니다.</h2>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        count: 0,
      },
    });
  </script>
</body>

 

 

- 로직이 길 때: 이벤트 발생 시 처리 로직을 v-on 라인에 넣기 힘들다. 이 때문에 v-on에서는 이벤트 발생시 처리해야 하는 method의 이름을 받아 처리한다.

(함수로 전달할 인자가 없으면 자동으로 event가 생성된다. v-on:click="hahaha"의 경우 인자를 작성하지 않았으므로 )

<body>
  <div id="app">
    <button v-on:click="hahaha">클릭</button>
  </div>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        name: "모두의 향연",
      },
      methods: {
        hahaha: function () {
          alert("하하하하하하 어서오세요~" + this.name + "블로그입니다.");
        },
      },
    });
      // 또한 JavaScript를 이용해서 메소드를 호출할 수 있습니다.
      //vm.hahaha(); // => '하하하하하하 어서오세요~모두의 향연블로그입니다.!'
  </script>
</body>

 

- 원본 DOM 이벤트에 액세스 해야 하는 경우 특별한 $event 변수를 사용해 메서드에 전달할 수도 있다.

<body>
  <div id="app">
    <form action="http://www.naver.com">
      <button v-on:click="test1('여러분')">test1</button>
      <button v-on:click="test2($event,'여러분')">test2</button>
    </form>
  </div>
  <script>
    new Vue({
      el: '#app',
      methods: {
        test1: function (msg) {
          alert("Hello" + msg + "!");
          console.dir(event.target);
        },
        test2: function (e, msg) {
          if (e) e.preventDefault();
          alert('Hello' + msg + "!");
          console.dir(e.target);
        },
      },
    });
  </script>
</body>

form에서 button을 만들면 '제출'이 자동으로 되기 때문에 v-on:click으로 alert를 띄우고 싶으면 $event로 인자 값 넘겨주기

 

 

📌 페이지 이동 방법

① @click="메서드이름"해놓고 메서드에서 e.preventDefault();쓰기  //이름만 가지고 호출했을 때 이벤트 받을 수 있음(=$event 안 써도 됨)

@click.prevent쓰기

<body>
  <div id="app">
    <h2>페이지 이동</h2>

    <a href="http://www.naver.com" @click="sendMsg1">이동</a>
    <a href="http://www.naver.com" @click="sendMsg2">이동막기1</a> 
    <a href="http://www.naver.com" @click.prevent="sendMsg1">이동막기2</a>
  </div>
  <script>
    new Vue({
      el: '#app',
      methods: {
        sendMsg1() {
          alert('이동할까요?');
        },
        sendMsg2(e) {
          e.preventDefault();
          alert('이동막기');
        },
      },
    });
  </script>
</body>

 

 

📌키 수식어: @keyup / @ keyup.enter / @keyup.13

: 키 수식어는 체이닝이 가능하다. enter도 쓰고싶고 space도 쓰고 싶으면 '.enter.space'이런식으로 연결지으면 된다.

<body>
  <div id="app">
    <h2>key 이벤트</h2> <br>
    <input placeholder="입력하세요" v-model="input" @keyup="send" /><br>
    <input placeholder="입력하세요" v-model="input" @keyup.enter="send" /><br>
    <input placeholder="입력하세요" v-model="input" @keyup.13="send" /><br>
    <button @click.once="sendId">검색</button>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        input: '',
      },
      methods: {
        send() {
          alert(this.id);
        },
      },
    });
  </script>
</body>

💡그 외 key수식어

.enter (.13) .tab .delete .esc .space .up .down .left .right

 

📌아이디 유효성 검사

<body>
    <div id="app">
        <h2>아이디 유효성 검사</h2>
        아이디: <input type="text" name="" id="" v-model="id">
        <button v-on:click="idCheck">아이디 중복 체크</button>
        <p>{{msg}}</p>
    </div>

    <script>
        new Vue({
            el: "#app",
            data() {
                return {
                    id: "",
                    msg: "",
                }
            },
            methods: {
                idCheck() {
                    if (this.id.length < 5 || this.id.length > 12) {
                        this.msg = "아이디는 5자리 이상 12자리 이하입니다.";
                        return;
                    } else {
                        if (this.id === "ssafy") {
                            this.msg = `${this.id}는 사용하실 수 없습니다.`;
                        } else {
                            this.msg = `${this.id}는 사용하실 수 있습니다.`;
                        }
                    }
                }
            },
        })
    </script>
</body>

 

 

✔️CSS class binding

📌 클릭 시 css 변경하기(색깔)

: <div v-bind:class="{ active: isActive }">VueCSS적용</div> //클래스 이름이 active이고, 그것을 변숫값 isActive일 때

<body>
  <div id="app">
    <div v-bind:class="{active:isActive}"></div>
    <button v-on:click="toggle">색깔변경</button>
  </div>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        isActive: false,
      },
      methods: {
        toggle: function () {
          this.isActive = !this.isActive;
        },
      },
    });
  </script>
</body>

 <div v-bind:class="{ active: isActive, ab: isActive }">처럼 클래스도 여러 개 설정해서 여러 개의 CSS설정 가능하다.

 

 

 

📌CSS class binding: 클릭시 css 변경하기(글자 변경)

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Vue.js</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <style type="text/css">
    .completed {
      text-decoration: line-through;
      font-style: italic;
    }
  </style>
</head>

<body>
  <div id="app">
    <ul>
      <li :class="{completed: todo.done}" :style="fontStyle" v-for="todo in todos">
        {{todo.msg}}
        <button @click="complete(todo)" class="btn">완료</button>
      </li>
    </ul>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        todos: [
          {
            msg: "오늘 할일 무조건 끝내기",
            done: false,
          },
          {
            msg: "알고리즘 1풀기",
            done: false,
          },
          {
            msg: "cs공부하기",
            done: false,
          },
        ],
        fontStyle: {
          fontSize: '20px',
        }
      },
      methods: {
        complete: function (todo) {
          if (!todo.done) {
            todo.msg = todo.msg + '완료';
            todo.done = !todo.done;
            event.target.innerText = "취소";
          } else {
            todo.msg = todo.msg.substr(0, todo.msg.indexOf("완료"));
            todo.done = !todo.done;
            event.target.innerText = "완료";
          }
        },
      },
    });
  </script>
</body>

 

 

 

✔️ form - input binding

: v-model directive를 사용하여 폼 input과 textarea element에 양방향 데이터 바인딩을 생성

 

📌text, textarea

: value속성과 input이벤트를 사용, v-model뒤에 수식어가 붙을 수 있다.

https://kr.vuejs.org/v2/guide/forms.html#%EC%88%98%EC%8B%9D%EC%96%B4

 

폼 입력 바인딩 — Vue.js

Vue.js - 프로그레시브 자바스크립트 프레임워크

kr.vuejs.org

.trim 앞 뒤 공백제거, 중간에 있는 공백은 제거 안됨(제거 되는것처럼 보이지만 html에서는 100칸을 띄어도 1칸 적용)
.lazy 입력 후 변화가 생겼을 때 이벤트 발생
.number 아무리 숫자를 입력해도 문자열로 인식되는데, 그걸 숫자로 바꿔줌 / 문자열을 입력한다면 그냥 문자열로 인식됨

type:text + data: 문자열 + vmodel: .number = input에는 문자가 쓰여지긴해! 하지만 number로 인식

type:number + data: 문자열 + vmodel: .number = input에는 숫자만 쓰여짐

일단 쓰여지는건 type에 따르고 data의 값의 여부와 상관없이 최종은 .number설정

<body>
  <div id="app">
    <div>
      이름 :
      <input v-model.trim="name" placeholder="이름을 입력하세요" />
      <!-- v-model은 기본적으로 모든 key stroke가 발생할 때마다 값을 업데이트 시킨다.
           .lazy 수식어를 추가하여 change 이벤트 이후에 동기화 할 수 있습니다. -->
      <input v-model.lazy="name" placeholder="이름을 입력하세요" />
      <input v-model.number="name" placeholder="이름을 입력하세요" />
    </div>
    <div>
      메세지 :
      <textarea v-model="message" placeholder="내용을 입력하세요"></textarea>
    </div>
    <p>{{ name }} 님에게 보내는 메세지 : {{ message }}</p>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        name: '',
        message: '',
      },
    });
  </script>
</body>

 

 

📌단일 checkbox

: 하나의 체크박스는 단일 boolean 값을 갖는다(v-model을 쓰면 true와 false 둘 중 하나)

+'true' ; 'false'말고 다른 이름으로 할 수도 있다(true-value="Y" false-value="N")

<body>
  <div id="app">
    <div>
      <p>
        이메일 수신
        <input type="checkbox" id="emailYN" v-model="email" />
        <label for="emailYN">{{ email }}</label>
      </p>
    </div>
    <div>
      <p>
        SMS 수신
        <input type="checkbox" id="smsYN" v-model="sms" true-value="Y" false-value="N" />
        <label for="smsYN">{{ sms }}</label>
      </p>
    </div>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        email: false,
        sms: 'Y',
      },
    });
  </script>
</body>

 

📌여러개 checkbox를 배열로

: v-model은 동일하게 연결하고 data()엔 하나의 변수만 설정한다. 체크박스 value값이 반환된다.

체크박스는 여러개 받을 수 있어 data가 배열인 것이다.

<body>
    <div id="app">
        <div>
            <p>당신이 가고 싶은 여행지를 선택하시오</p>
            <input type="checkbox" name="" id="" value="인도" v-model="checkedArea">인도
            <input type="checkbox" name="" id="" value="일본" v-model="checkedArea">일본
            <input type="checkbox" name="" id="" value="괌" v-model="checkedArea">괌
            <input type="checkbox" name="" id="" value="캐나다" v-model="checkedArea">캐나다
            <input type="checkbox" name="" id="" value="태국" v-model="checkedArea">태국
            체크한 이름:{{checkedArea}}
        </div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data() {
                return {
                    checkedArea: [],
                }
            }
        })
    </script>
</body>

 

📌radio

: v-model은 동일하게 연결하고 data()엔 하나의 변수만 설정한다. 라디오 value값이 반환된다.

라디오는 선택지 중에 하나만 선택할 수 있어서 data에 배열이 올 수 없다.

data에 value와 똑같이 설정하면 기본값으로 출력된다.

<body>
    <div id="app">
        <div>
            <p>당신이 가고 싶은 여행지를 선택하시오</p>
            <input type="radio" name="" id="" value="인도" v-model="checkedArea2">인도
            <input type="radio" name="" id="" value="일본" v-model="checkedArea2">일본
            <input type="radio" name="" id="" value="괌" v-model="checkedArea2">괌
            <input type="radio" name="" id="" value="캐나다" v-model="checkedArea2">캐나다
            <input type="radio" name="" id="" value="태국" v-model="checkedArea2">태국
            <div>
                체크한 이름: {{checkedArea2}}
            </div>
        </div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data() {
                return {
                   checkedArea2: '괌',
                }
            }
        })
    </script>
</body>

 

📌select(단일기능)

<body>
    <div id="app">
          <div>
            <p>당신이 가고 싶은 여행지를 선택하시오</p>
            <select v-model="selectArea">
                <option disabled value="">선택하세요</option>
                <option value="인도">인도</option>
                <option value="일본">일본</option>
                <option value="괌">괌</option>
                <option value="캐나다">캐나다</option>
                <option value="태국">태국</option>
            </select>
            <div>
                체크한 이름: {{selectArea}}
            </div>
        </div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data() {
                return {
                   selectArea: '인도',
                }
            }
        })
    </script>
</body>

 

📌select (다중기능)

: multiple을 붙임, data를 배열로 설정, ctrl을 누른 상태에서 선택하면 다중 선택됨

<body>
    <div id="app">
          <div>
            <p>당신이 가고 싶은 여행지를 선택하시오</p>
            <select v-model="selectArea" multiple>
                <option disabled value="">선택하세요</option>
                <option value="인도">인도</option>
                <option value="일본">일본</option>
                <option value="괌">괌</option>
                <option value="캐나다">캐나다</option>
                <option value="태국">태국</option>
            </select>
            <div>
                체크한 이름: {{selectArea}}
            </div>
        </div>
    </div>
    <script>
        new Vue({
            el: "#app",
            data() {
                return {
                   selectArea: [],
                }
            }
        })
    </script>
</body>

 

📌v-for을 이용하여 다중 배열 생성

<body>
  <div id="app">
    <div>
      <p>당신이 가고 싶은 여행지를 선택하시오</p>
        <select v-model="selectArea">
            <option v-for="(area, index) in areas" :key="index" v-bind:value="area.value">
                {{area.text}}</option>
        </select>
        <span>선택한 지역 : {{selectArea}}</span>
  </div>
  
  <script>
    new Vue({
      el: '#app',
      data: {
        selectArea: '',
        areas: [
            { text: "인도", value: "인도" },
            { text: "일본", value: "일본" },
            { text: "괌", value: "괌" },
            { text: "캐나다", value: "캐나다" },
            { text: "태국", value: "태국" },
        ],
      },
      created() {
        param = '인도';
        this.selectArea = param;
      },
    });
  </script>
</body>
728x90
반응형