개발/Vue.js

[Vue 스터디 #3] 디렉티브, 이벤트, 양방향 바인딩, Watchers

TutleKing 2024. 11. 12. 20:12

디렉티브 (directives = 지시어)

  • v-접두사가 있는 특수 속성
  • 종류
    • v-text
    • v-html
    • v-show
    • v-if
    • v-else
    • v-else-if
    • v-for
    • v-on (단축표기 @) * 중요
    • v-bind (단축표기 :) * 중요
    • v-model
    • v-slot (단축표기 #) * 중요
    • v-pre
    • v-once
    • v-cloak
    • v-memo (v3.2+)

      디렉티브 구성

  • 디렉티브(directives) : v- 접두사가 있는 특수 속성으로, 디렉티브의 값(value)이 변경될 때 특정 효과를 반응적으로 DOM에 적용하는 것을 말함
  • 전달인자(Argument) : 일부 디렉티브는 디렉티브명 뒤에 콜론(:)으로 표기되는 전달인자
  • 수식어(Modifiers) : 수식어는 점(.)으로 표시되는 특수 접미사

이벤트

  • v-on 사용 -> @로 축약
    // 인라인 핸들러
    <div>
    <button @click="counter += 1">counter {{ counter }}</button>
    </div>
    

// 메서드 핸들러
const printEventInfo = (event) => {
console.log(event.target);
console.log(event.target.tagName);
};

``` ## 이벤트 객체 접근 - 인라인 핸들러에서 event 객체에 접근 하기 위해서는 `$event` 를 인자로 추가해야한다 - arrow function 을 사용하는 경우, 특수문자를 쓰지 않아도 됨 (=event) ```js methods: { warn(message, event) { // 이제 네이티브 이벤트 객체에 접근할 수 있습니다. if (event) { event.preventDefault() } alert(message) } }

// 특수한 키워드인 $event 사용
<button @click="warn('아직 양식을 제출할 수 없습니다.', $event)">
제출하기

// 인라인 화살표 함수 사용
<button @click="(event) => warn('아직 양식을 제출할 수 없습니다.', event)">
제출하기

## 이벤트 수식어 
- `.stop` = `e.stopPropagation()` - `.prevent` = `e.preventDefault()` - `.capture` = 캡처 모드를 사용할 때 이벤트 리스너를 사용 - `.self` = 오로지 자기 자신만 호출할 수 있다. 즉, 타깃요소가 `self`일 때 발동 - `.once` = 해당 이벤트는 **한 번만** 실행 - 키 수식어 - `.enter` - `.tab` - `.delete` (”Delete”와 “Backspace” 키 모두를 수신합니다.) - `.esc` - `.space` - `.up` - `.down` - `.left` - `.right` - 시스템 키 수식어 - - `.ctrl` - `.alt` - `.shift` - `.meta` (mac의 cmd키, window의 win 키) - `.exact` 수식어 (정확하게 해당 키만 사용 필요) - ex) `<button @click.ctrl.exact="onCtrlClick">A</button>` - 마우스 버튼 수식어 - `.left` - `.right` - `.middle` # 양방향 바인딩 - `v-model` 로 아래 동작을 커버할 수 있음 - text, textarea : `value`, `@input` - checkbox, radio : : `checked`, `change` - select : `value`, `change` - v-model modifiers - `.lazy`, `.number`, `.trim` ```js // App.vue <script> import CustomInput from './CustomInput.vue' export default { components: { CustomInput }, data() { return { message: 'hello' } } } </script> <template> <CustomInput :model-value="message" @update:model-value="newValue => message = newValue"/> // => v-model="message" 로 치환 가능 {{ message }} </template> // CustomInput.vue <script> export default { props: ['modelValue'], emits: ['update:modelValue'] // update시 prop 을 콜론 뒤에 사용하는 구문 } </script> <template> <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </template>

checkBox 예제

<script>
export default {
  data() {
    return {
      checkboxValues: [], // true로 변경 하면 하나 체크시 다 체크됨 
    }
  }
}
</script>

<template>
  <div>
  <label>
    <input type="checkbox" v-model="checkboxValues" value="html" />
    HTML
  </label>
  <label>
    <input type="checkbox" v-model="checkboxValues" value="css" />
    CSS
  </label>
  <label>
    <input type="checkbox" v-model="checkboxValues" value="javascript" />
    JavaScript
  </label>
  <p>
    {{ checkboxValues }}
  </p>
</div>
</template>

Watchers

watch

  • 상태감지시 사용
    • watch(/* Source Type */, (newValue, oldValue) => {});
    • Source Type에는 다양한 type이 올 수 있음.
      // getter
      watch(
      () => x.value + y.value,
      (sum) => {
      console.log(`sum of x + y is: ${sum}`)
      }
      )

      깊은 감시자

  • watch 는 기본적으로 얕음
    • 오브젝트가 새롭게 변경(갈아치워지는)되는 때만 watch 가 동작
    • 깊은 감시자를 실행시키고 싶다면 deep: true 사용
      export default {
      watch: {
      someObject: {
        handler(newValue, oldValue) {
          // 참고: 객체 자체가 교체되지 않는 한,
          // 중첩된 변경 시 `newValue`는
          // `oldValue`와 동일합니다.
        },
        deep: true
      }
      }
      }

Eager 감시자

  • watch 는 기본적으로 지연(lazy) 모드
    • immediate: true 속성 추가로 즉시 실행 가능

명령형 선언 - this.$watch()

export default {
  created() {
    this.$watch('question', (newQuestion) => {
      // ...
    })
  }
}

JS 참고

1. event.preventDefault(), event.stopPropagation()

https://programmingsummaries.tistory.com/313

  • event.preventDefault() : 현재 이벤트의 기본 동작을 중지
    • 아래의 예제에서 a 태그를 클릭하면, div의 alert 까지 같이 동작하는 것이 원래 동작이지만, 개발자는 a 태그의 href로 이동하는 기능을 "끄고 싶을 때" event.preventDefault() 를 사용
      <div @click="alert('ABC')">
      <a href="aaa.com"></a>
      </div>
  • event.stopPropagation() : 현재 이벤트가 상위로 전달되지 않게 함
    • 아래 예제에서 GHI alert 만 띄우고 싶지만, 상위 ABC alert 까지 뜨게됨. event.stopPropagation() 을 사용한다면 GHI alert만 뜸
      • 그러나 DEF 부분에서 누른다면 내부의 GHI alert은 뜨게됨.
      • 이때 쓸 수 있는 메서드는 event.stopImmediatePropagation()
        <div @click="alert('ABC')">
        <div @click="alert('DEF')">
        <div @click="alert('GHI')">
        </div>
        </div>
        </div>
반응형