FrameWorks/Vue

Vue의 ObjectBinding

ABCD 2024. 6. 12.

Object binding

v-text

  • Expects: String
  • 태그 안에 text값을 input 시키는 것
  • innerTEXT와 같다(?)
<span v-text="msg"></span>
<!-- same as -->
<span>{{ msg }}</span>

v-html

  • Expects: String
  • 태그 안에 html을 input 시키는 것
  • innerHTML과 같다(?)
<script>
  export default {
    data() {
      return{
        htmlString: '<a href="www.naver.com">네이버</a>'
      }
    }
  }
</script>

<template>
    <p v-html="htmlString"></p>
</template>

스크린샷 2023-08-07 오전 11 12 36


v-show

  • Expects: Any
  • 표현식 값의 진위 여부에 따라 요소를 보이게 or 안보이게 하는 것
  • v-show가 포함되어 있는 요소는 항상 랜더링되어 DOM에 남아있지만, CSS속성만 토글한다.
    • 즉, v-if는 랜더링에서 조건이 거짓이면 DOM에 없지만, v-show는 DOM에는 남아 있다.
<h1 v-show="ok">Hello!</h1>  <!-- ok는 변수로 Boolean값을 갖는다 -->

v-if & v-else & v-else-if

  • Expects: Any
  • 조건문을 사용 할 수 있다.
    • tymleaf의 th:if와 같다고 생각하면 된다.
<div v-if="Math.random() > 0.5">
  Now you see me
</div>
<div v-else>
  Now you don't
</div>
<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>

v-for

  • Expects: Array | Object | number | String | Iterable
  • 반복문의 특성은 여러가지가 있다.
    data() {
      return {
        parentMessage: 'Parent',
        items: [{ message: 'Foo' }, { message: 'Bar' }]
      }
    }
  • Alias를 이용하는 기본적인 방법(인자 1개)
        <li v-for="item in items">
          {{ item.message }}
        </li>
  • 인덱스를 주는 방법(인자 2개)
        <li v-for="(item, index) in items">
          {{ parentMessage }} - {{ index }} - {{ item.message }}
        </li>
  • value, key, index를 주는 방법(인자 3개)
        <script>
        export default {
          data() {
              return {
                myObject: {
                  title: 'How to do lists in Vue',
                  author: 'Jane Doe',
                  publishedAt: '2016-04-10'
                }
              }
            }
        }
        </script>

        <template>
            <ul>
            <li v-for="(value, key, index) in myObject">
                  {{ index }}. {{ key }}: {{ value }}
                </li>
          </ul>
        </template>

        <!--

        0. title: How to do lists in Vue
        1. author: Jane Doe
        2. publishedAt: 2016-04-10

        -->
  • Alias를 이용하지 않고 바로 데이터를 꺼내는 방법
        <li v-for="{ message } in items">
          {{ message }}
        </li>

        <!-- index사용 -->

        <li v-for="({ message }, index) in items">
          {{ index }} - {{ message }}
        </li>
  • 중첩된 for문을 사용 할 수도 있다.
        <!-- 상위 접근도 가능함 -->
        <li v-for="item in items">
          <span v-for="childItem in item.children">
            {{ item.message }} {{ childItem }}
          </span>
        </li>
        <div v-for="item of items"></div>
  • 여러개의 템플릿을 생성하게 할수도 있다.
        <ul>
          <template v-for="item in items">
            <li>{{ item.msg }}</li>
            <li class="divider" role="presentation"></li>
          </template>
        </ul>
  • v-for와 v-if를 활용하여 선택적으로 반복할 수 있게 만들 수 있다.
        <template v-for="todo in todos">
          <li v-if="!todo.isComplete">
            {{ todo.name }}
          </li>
        </template>
  • Component에도 v-for을 사용할 수 있다.
        <MyComponent
          v-for="(item, index) in items"
          :item="item"
          :index="index"
          :key="item.id"
        />

:is

  • v-for를 사용 했을 경우 유용하다.
  • 해당 조건을 만들어 조건별로 Component를 다르게 호출해 사용 할 수 있게 만들어 줄 수 있다.
  • 하지만 해당 props을 반드시 해당 Component에 정의해야 한다.
<template>
  <ul>
    <li v-for="(item, index) in items" :key="index" :is="getComponent(item.type)" :item="item">
      {{ item.name }}
    </li>
  </ul>
</template>

<script setup>
const items = reactive(
        [
          { type: 'apple', name: '사과' },
          { type: 'banana', name: '바나나' },
          { type: 'orange', name: '오렌지' },
        ]
);

function getComponent(type){
  switch (type) {
    case 'apple':
      return 'AppleItem'
    case 'banana':
      return 'BananaItem'
    case 'orange':
      return 'OrangeItem'
    default:
      return 'DefaultItem'
  }
}
</script>
// AppleItem.vue
export default {
  props: ['item'],
  // ...
}

// BananaItem.vue
export default {
  props: ['item'],
  // ...
}

// OrangeItem.vue
export default {
  props: ['item'],
  // ...
}

유의사항

  • Vue는 v-for로 랜더링된 요소 목록을 업데이트할 때 기본적으로 “제자리 패치”를 사용한다.
    • 효율적이지만 목록 랜더링 출력이 하위 Component 상태나 임시 DOM에 의존하지 않는 경우 적합
    • 반복되는 DOM 컨텐츠, 성능향상을 위해 의도적으로 사용하는 경우에 적합
  • key값을 지정해서 사용하는 것이 더 좋다.
<div v-for="item in items" :key="item.id">
  <!-- content -->
</div>

<!-- example -->
<template v-for="todo in todos" :key="todo.name">
  <li>{{ todo.name }}</li>
</template>

v-on

  • Expect: Function | Inline Statement | Object (without argument)
  • shortCut: @
  • Argument: event (optional if using Obecjt syntax)
  • Event Modifiers
    • .stop - event.stopPropagation()을 호출.
    • .prevent - event.preventDefault()을 호출.
    • .capture - 캡쳐 모드에서 이벤트 리스너를 추가.
    • .self - 이 요소에서 이벤트가 디스패치된 경우에만 핸들러를 트리거.
    • .once - 최대 한번만 핸들러를 트리거.
    • .passive - { passive: true }로 DOM이벤트를 첨부.
  • Key Modifiers
    • .{keyAlias} - 특정 key에서만 핸들러를 트리거
    • .enter - enter 키에 반응
    • .tab -tab 키에 반응
    • .delete - delete or backSpace 키에 반응
    • .esc - esc 키에 반응
    • .space - space 키에 반응
    • .up - 방향키 up 키에 반응
    • .down - 방향키 down 키에 반응
    • .left - 방향키 left 키에 반응
    • .right - 방향키 right 키에 반응
  • System Modifier Keys
    • .ctrl - control 키에 반응
    • .alt - window의 alt, mac의 option 키에 반응
    • .shift - shift 키에 반응
    • .meta - window의 windows key, mac의 command key 등 키에 반응
  • Exact Modifier Key
    • .exact - 이벤트를 트리거 할 때 시스템 수정자의 정확한 조합이 있어야만 제어 할 수 있게 설정
    • <!-- shift만 눌려있다면 어떠한 키가 눌려있어도 클릭시 이벤트 트리거 호출 --> <button @click.shift="onClick">A</button> <!-- shift만 누른 상태에서 클릭시 이벤트 트리거 호출 --> <button @click.shift.exact="onCtrlClick">A</button> <!-- System Modifier Keys중 아무것도 안 눌린상태에서만 이벤트 트리거 호출 --> <button @click.exact="onClick">A</button>
  • Mouse Button Modifiers
    • .left - 마우스 왼쪽 버튼 이벤트 설정.
    • .right - 마우스 오른쪽 버튼 이벤트 설정.
    • .middle - 마우스 휠 버튼 이벤트 설정.
  • 수정자 사용시 주의사항
    • 연속해서 수정자를 사용 할 경우 관련 코드가 동일한 순서로 생성되므로 순서가 중요하다.

ex)

@click.prevent.self ← 요소 자체와 하위 요소에 대한 클릭의 기본 동작을 방지
@click.self.prevent ← 요소 자체에 대한 클릭의 기본 동작만 방지

Function (Method Handlers)

  • 함수를 만들어 해당 함수를 직접 바인딩 시키는 것
<script>
const name = ref('Vue.js')

function greet(event) {
  alert(`Hello ${name.value}!`)
  // `event` is the native DOM event
  if (event) {
    alert(event.target.tagName)
  }
}
</script>

<template>
  <button @click="greet">Greet</button>
</template>
  • 함수에 인자값이 넣어 해당 이벤트를 실행
<script>
function say(message) {
  alert(message)
}
</script>

<template>
  <button @click="say('hello')">Say hello</button>
  <button @click="say('bye')">Say bye</button>
</template>

Inline Statement (Inline Handlers)

  • 해당 태그안에 직접 이벤트를 명시해서 사용하는 것
<script>
  const count = ref(0);
<script>

<template>
  <button @click="count++">Add 1</button>
  <p>Count is: {{ count }}</p>
</template>
<script>
function warn(message, event) {
  // now we have access to the native event
  if (event) {
    event.preventDefault()
  }
  alert(message)
}
</script>

<template>
  <!-- using $event special variable -->
  <button @click="warn('Form cannot be submitted yet.', $event)">
    Submit
  </button>

  <!-- using inline arrow function -->
  <button @click="(event) => warn('Form cannot be submitted yet.', event)">
    Submit
  </button>
</template>

v-bind

  • Expects: Any(with argument) | Object (without argument)
  • shortCut: : “ or “ . (when using .prop modifier)
  • Argument: Attr or Prop (optional)
  • Modifiers
    • .camel - Kebab-case를 camelCase로 변경시킨다.
    • .prop - 바인딩이 DOM property로 강제로 설정된다.
      • 해당 문구는 v-bind: or shortCut인 : 를 사용하지 않고 .을 사용해도 된다.
    • .attr - 바인딩이 DOm attribute로 강제로 설정된다.
  • v-bind: or : or . 뒤에 붙어있는 속성값에 명시한 데이터를 바인딩 시킨다고 생각하면 쉽다.
<img v-bind:src="imageDir" />
<button v-bind:[key]="value"></button>

<!-- 해당 구문은 아래와 같이 바인딩 된다.-->

<img src="imageDir" />
<button [key]="value"></button>
  • 하위 property에 바인딩해서 사용해야 하는 경우 하위 Component에 제대로 명시한 후 사용해야 한다.
<MyComponent v-bind="$props" /> <!-- 공통의 prop들을 자식에게 전달한다. -->
<!-- 또는 -->
<MyComponent :${propName}="somThing" /> <!-- 자식의 prop이 정의 되어 있어야 한다. -->

.camel

  • HTML은 기본적으로 대소문자를 구분하지 못한다.
  • 그렇기 때문에 기본적으로 Kebab-case를 사용하는데, Camel-case를 인식할 수 있도록 해준다.
    • Kebab-caseex) CSS의 단어들은 모두 - (하이픈)으로 구분한다.
    • → - (하이픈)을 사용하여 단어사이를 구분하는 표기법
  • 일반적으로 사용하지 않아도 괜찮다. 하지만, SVG태그의 경우 kebab-case로 작성된 경우가 많아 해당 태그에서는 .camel을 사용해주는 것이 좋다.

v-model

  • 데이터를 입력함과 동시에 해당 데이터를 변경 시킨다.
    • getter와 setter를 동시에 한다고 생각하면 된다.
  • <input>, <select>, <textarea>, Components에 한에서만 사용 가능하다.

v- pre

  • 컴파일 하지 않고 해당 태그는 그냥 넘어간다. 때문에 일반 문자처럼 화면에 보여지게 된다.
<template>
  <div>
    <h3>Vue.js v-pre 예제</h3>
    <span v-pre>{{ this will not be compiled }}</span>
  </div>
</template>

<!-- 브라우저에서 보여지는 결과는 아래와 같이 나온다 -->

{{ this will not be compiled }}

v-once

  • 최초 한번만 렌더링 하고 차후 업데이트는 skip한다.
  • 데이터의 변경가 변경되나 최초 원본을 계속 보여주고 싶을 때 사용(?)

v-memo

  • v-once 에서 발전된 기능으로 조건을 추가 할 수 있게 만들어 졌다.
  • 어떠한 값에 의존하여 해당 값이 변경 될 때에만 새로 렌더링하도록 구성되어 있다.
  • 논리가 많거나 복잡한 경우에 특히 유용하다.
<template v-memo="[dependencies]">
  <!-- memoized content -->
</template>

ex) count가 변경되지 않으면 해당 component는 리렌더링 하지 않는다.

<template>
  <div>
    <template v-memo="[count]">
      <h3>클릭 횟수: {{ count }}</h3> 
    </template>
    <button @click="increment">클릭</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    }
  },
};
</script>

v-cloak

  • 준비 될 때까지 컴파일 되지 않은 템플릿을 숨긴다.
  • DOM템플릿 사용시 컴파일되지 않은 템플릿을 flash할 수 있다.
  • 이 때, 컴파일되지않아 표현할 것이 없는 템플릿들을 처리하게 해준다.
  • ex) 컴파일되지 않은 템플릿들을 숨기기 위해 CSS와 결합하여 사용 할 수 있다.*
    <style scoped>
    [v-cloak] {
      display: none;
    }
    </style>

    <div v-cloak>
      {{ message }}
    </div>
728x90
반응형

댓글

💲 추천 글