danbibibi
article thumbnail
Published 2023. 5. 5. 15:55
[Vue 기초 3] Event, Binding WEB/front-end

1. v-on

DOM 이벤트를 듣고 해당 이벤트가 발생되면, 지정된 메소드를 호출

<html />
<!DOCTYPE html> <html lang="en"> <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> </head> <body> <div id="app"> <button v-on:click="counter += 1">클릭</button> <p>위 버튼을 클릭한 횟수는 {{counter}} 번 입니다.</p> </div> <script> new Vue({ el: '#app', data: { counter: 0, }, }); </script> </body> </html>
v-on:click = @click

 

2. method Event Handler

  • 이벤트 발생시 처리 로직을 v-on에 모두 넣기는 힘듦
  • v-on에서는 이벤트 발생시 처리해야 하는 method의 이름을 받아 처리
<html />
<!DOCTYPE html> <html lang="en"> <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> </head> <body> <div id="app"> <button v-on:click="greet">Greet</button> </div> <script> var vm = new Vue({ el: "#app", data: { name: "DANBI", }, methods: { greet: function (event) { alert("Hello " + this.name + "!"); console.dir(event.target); }, }, }); // JavaScript를 이용한 메소드를 호출도 가능 //vm.greet(); // => 'Hello Vue.js!' </script> </body> </html>

 

3. Inline Event Handler

  • 메소드 이름을 직접 바인딩 하는 대신 인라인 JavaScript 구문에 메소드를 사용할 수도 있음
  • 원본 DOM 이벤트에 엑세스 해야 하는 경우 특별한 $event 변수를 사용해 메소드에 전달할 수도 있음
<html />
<!DOCTYPE html> <html lang="en"> <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> </head> <body> <div id="app"> <form action="http://www.naver.com"> <button v-on:click="greet1('HARRY')">Greet</button> <button v-on:click="greet2($event, 'DOBI')">Greet</button> </form> </div> <script> new Vue({ el: '#app', methods: { greet1: function (msg) { alert('Hello ' + msg + '!'); console.dir(event.target); }, greet2: function (e, msg) { if (e) e.preventDefault(); alert('Hello ' + msg + '!'); console.dir(e.target); }, }, }); </script> </body> </html>

 

4. Event Modifier (이벤트 수식어)

  • method는 DOM의 이벤트를 처리하는 것 보다 data 처리를 위한 로직만 작업하는 것이 좋음
  • 이 문제를 해결하기 위해, Vue는 v-on 이벤트 수식어를 제공
  • 수식어는 점으로 표시된 접미사
<html />
<!-- 클릭 이벤트 전파 중단 --> <a v-on:click.stop="doThis"></a> <!-- 제출 이벤트가 페이지를 다시 로드 하지 않음 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 수식어는 체이닝 가능 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 단순히 수식어만 사용 가능 --> <form v-on:submit.prevent></form>

 

<html />
<!DOCTYPE html> <html lang="en"> <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> </head> <body> <div id="app"> <h2>페이지 이동</h2> <a href="test.html" @click="sendMsg1">페이지 이동 막기1</a><br /> <a href="test.html" @click="sendMsg2">페이지 이동 막기2</a><br /> <a href="test.html" @click.prevent="sendMsg1">페이지 이동 막기3</a><br /> </div> <script> new Vue({ el: '#app', methods: { sendMsg1() { alert('이동할까요?'); }, sendMsg2(e) { e.preventDefault(); alert('이동막기'); }, }, }); </script> </body> </html>

 

5. Key Modifier (키 수식어)

Vue는 키 이벤트를 수신할 때 v-on에 대한 키 수식어를 추가할 수 있음

<html />
<input v-on:keyup.enter="submit">
key code
.enter (.13)
.tab
.delete (Delete, Backspace 모두 캡처)
.esc
.space
.up
.down
.left
.right

 

6. ref, $refs

  • 뷰에서는 $refs 속성을 이용해 DOM에 접근할 수 있음
  • 단, 뷰의 가장 중요한 목적 중 하나는 개발자가 DOM을 다루지 않게 하는 것이므로, 되도록 ref 사용을 피하는 것이 좋음
<html />
<!DOCTYPE html> <html lang="en"> <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> .success { color: dodgerblue; } .fail { color: darkred; } </style> </head> <body> <div id="app"> <h2>엘리먼트 참조하기</h2> <!-- 아이디 : <input type="text" v-model="id"> --> 아이디 : <input type="text" v-model="id" ref="id" @keyup="idCheck" /> <button @click="idCheck">아이디 중복 체크</button> <div v-bind:class="{success : isSuccess, fail : isFail}" v-bind:style="myStyle" v-html="msg"></div> </div> <script> new Vue({ el: '#app', data: { id: '', msg: '', isSuccess: false, isFail: false, myStyle: { fontSize: '25px', }, }, methods: { idCheck() { if (this.id.length < 5 || this.id.length > 12) { this.msg = `아이디는 5자이상 12자리 이하입니다.`; this.$refs.id.focus(); console.dir(this.$refs.id); this.isSuccess = false; this.isFail = false; return; } else { if (this.id === 'dobi') { this.msg = `<b>${this.id}</b>는 사용할 수 없습니다.`; this.isSuccess = false; this.isFail = true; } else { this.msg = `<b>${this.id}</b>는 사용할 수 있습니다.`; this.isSuccess = true; this.isFail = false; } } console.log(this.$refs.id.value); }, }, }); </script> </body> </html>

 

 

7. CSS class binding

  • element의 class와 style을 변경
  • v-bind:class는 조건에 따라 class를 적용할 수 있음
<html />
<!DOCTYPE html> <html lang="en"> <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> .active { background: rgb(106, 148, 238); color: white; } div { width: 200px; height: 200px; border: 1px solid #444; } </style> </head> <body> <div id="app"> <div v-bind:class="{ active: isActive }">VueCSS적용</div> <button v-on:click="toggle">VueCSS</button> </div> <script type="text/javascript"> new Vue({ el: "#app", data: { isActive: false, }, methods: { toggle: function () { this.isActive = !this.isActive; }, }, }); </script> </body> </html>

 

8. From Input binding

  • text와 textarea 태그는 value 속성과 input 이벤트를 사용함
  • 체크박스들과 라디오버튼들은 checked 속성과 change 이벤트를 사용
  • select 태그는 value를 prop으로, change를 이벤트로 사용

 

8.1. text, textarea

* textarea(여러줄을 가진 문장)의 경우, 보간법이 작동하지 않음 → v-model 사용

<html />
<!DOCTYPE html> <html lang="en"> <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> </head> <body> <div id="app"> <div> 아이디 : <input v-model.trim="id" placeholder="아이디를 입력하세요" /> <input v-model.lazy="id" placeholder="아이디를 입력하세요" /> </div> <div> 메세지 : <textarea v-model="message" placeholder="내용을 입력하세요"></textarea> </div> <p>{{ id }} 님에게 보내는 메세지 : {{ message }}</p> </div> <script> new Vue({ el: '#app', data: { id: '', message: '', }, }); </script> </body> </html>
v-model은 기본적으로 사용자가 값을 변경할 때마다 자동으로 바인딩 갱신
.lazy 수식어를 추가하여 change 이벤트 이후에 동기화하도록 할 수 있음

 

8.2. checkbox

  • 하나의 체크박스는 단일 boolean 값을 가짐
  • 여러 개의 체크박스는 같은 배열을 바인딩 할 수 있음
  • 배열의 값과 cehckbox의 value 속성이 같을 경우 체크 처리됨
<html />
<!DOCTYPE html> <html lang="en"> <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> </head> <body> <div id="app"> <div> 가고 싶은 여행지를 선택하세요!</div> <input type="checkbox" id="seoul" value="서울" v-model="checkedAreas" /> <label for="seoul">서울</label> <input type="checkbox" id="busan" value="부산" v-model="checkedAreas" /> <label for="busan">부산</label> <input type="checkbox" id="jeju" value="제주" v-model="checkedAreas" /> <label for="jeju">제주</label> <input type="checkbox" id="daejeon" value="대전" v-model="checkedAreas" /> <label for="daejeon">대전</label> <input type="checkbox" id="gyeongju" value="경주" v-model="checkedAreas" /> <label for="gyeongju">경주</label> <br /> <span>체크한 이름: {{ checkedAreas }}</span> </div> <script> new Vue({ el: '#app', data: { checkedAreas: [], }, }); </script> </body> </html>

 

8.3. radio

선택된 항목의 value 속성의 값을 관리

<html />
<!DOCTYPE html> <html lang="en"> <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> </head> <body> <div id="app"> <div> 이번에 다녀온 여행지를 선택해주세요!</div> <div> <input type="radio" id="seoul" value="서울" v-model="ckArea" /> <label for="seoul">서울</label> <input type="radio" id="busan" value="부산" v-model="ckArea" /> <label for="busan">부산</label> <input type="radio" id="jeju" value="제주" v-model="ckArea" /> <label for="jeju">제주</label> <input type="radio" id="daejeon" value="대전" v-model="ckArea" /> <label for="daejeon">대전</label> <input type="radio" id="gyeongju" value="경주" v-model="ckArea" /> <label for="gyeongju">경주</label> </div> <span>선택한 지역 : {{ ckArea }}</span> </div> <script> new Vue({ el: '#app', data: { ckArea: '경주', }, }); </script> </body> </html>

 

8.4. select

  • 선택된 항목의 value 속성의 값을 관리
  • v-model 표현식의 초기 값이 어떤 옵션에도 없으면, <select> element는 “선택없음” 상태로 렌더링 됨
<html />
<!DOCTYPE html> <html lang="en"> <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> </head> <body> <div id="app"> <div> <p>여행지를 선택하세오</p> <select v-model="selectedArea"> <option disabled value="">선택하세요</option> <option value="seoul">서울</option> <option value="busan">부산</option> <option value="jeju">제주</option> <option value="daejeon">대전</option> <option value="gyeongju">경주</option> </select> </div> <span>선택한 지역 : {{ selectedArea }}</span><br /> </div> <script> new Vue({ el: '#app', data: { selectedArea: '', }, }); </script> </body> </html>

 

다음과 같이 v-for를 이용하여 동적 option 렌더링도 가능하다!

<html />
<!DOCTYPE html> <html lang="en"> <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> </head> <body> <div id="app"> <div> <p>여행지를 선택하세오</p> <select v-model="selectedArea"> <option v-for="option in options" v-bind:value="option.value">{{ option.text }}</option> </select> </div> <span>선택한 지역 : {{ selectedArea }}</span> </div> <script> new Vue({ el: '#app', data: { selectedArea: '', options: [ { text: '서울', value: 'seoul' }, { text: '부산', value: 'busan' }, { text: '대전', value: 'daejeon' }, { text: '경주', value: 'gyeongju' }, { text: '제주', value: 'jeju' }, ], }, created() { param = 'gyeongju'; this.selectedArea = param; }, }); </script> </body> </html>

 

8.5. form Modifiers (폼 수식어)

8.5.1. .lazy

change 이벤트 이후에 동기화 가능

<html />
<input v-model.lazy="msg">

 

8.5.2. .number

사용자 입력을 자동으로 숫자로 형 변환

<html />
<input v-model.number="age" type="number">

 

8.5.3. .trim

사용자 입력에서 양쪽 공백을 제거

<html />
<input v-model.trim="msg">
profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로