Skip to content

빌트인 디렉티브

v-text

엘리먼트의 텍스트 컨텐츠를 업데이트합니다.

  • 요구되는 값: string

  • 세부 사항:

    v-text는 엘리먼트의 텍스트 컨텐츠 속성을 설정하므로, 엘리먼트 내부의 기존 컨텐츠를 덮어씁니다. 텍스트 컨텐츠의 일부를 업데이트해야 하는 경우, 이중 중괄호를 사용해야 합니다.

  • 예제

    template
    <span v-text="msg"></span>
    <!-- 아래와 같음 -->
    <span>{{msg}}</span>
  • 참고: 템플릿 문법 - 텍스트 보간법

v-html

엘리먼트의 innerHTML을 업데이트합니다.

  • 요구되는 값: string

  • 세부 사항:

    v-html의 내용은 Vue 템플릿 문법을 처리하지 않고 일반 HTML로 삽입됩니다. v-html을 사용하여 템플릿을 작성하려고 한다면, 이 방법 대신 컴포넌트를 사용하여 해결하는 방법을 고민해봐야 합니다.

    보안 참고 사항

    웹사이트에서 임의의 HTML을 동적으로 렌더링하는 것은 XSS 공격으로 쉽게 이어질 수 있기 때문에 매우 위험할 수 있습니다. 신뢰할 수 있는 컨텐츠에만 v-html을 사용하고, 사용자가 제공하는 컨텐츠에는 절대 사용하면 안됩니다.

    싱글 파일 컴포넌트(SFC)에서 scoped(범위를 지정한) Style은 v-html 내부 컨텐츠에 적용되지 않습니다. 왜냐하면 해당 HTML은 Vue의 템플릿 컴파일러에서 처리되지 않기 때문입니다. 범위를 지정한 CSS로 v-html 컨텐츠를 대상으로 지정하려는 경우, CSS 모듈 또는 BEM과 같은 수동 범위 지정 방법과 함께 전역 <style> 엘리먼트를 사용할 수 있습니다.

  • 예제

    template
    <div v-html="html"></div>
  • 참고: 템플릿 문법 - HTML 출력

v-show

표현식의 truthy 값을 기반으로 엘리먼트의 가시성을 전환합니다.

  • 요구되는 값: any

  • 세부 사항:

    v-show는 인라인 스타일을 통해 display CSS 속성을 설정하며, 엘리먼트가 표시될 때 초기 display 값을 설정하려고 시도합니다. 또한 조건이 변경될 때 전환을 트리거합니다.

  • 참고: 조건부 렌더링 - v-show

v-if

표현식의 truthy 값을 기반으로 엘리먼트 또는 템플릿 일부를 조건부로 렌더링합니다.

  • 요구되는 값: any

  • 세부 사항:

    v-if 엘리먼트가 토글되면, 엘리먼트와 여기에 포함된 디렉티브/컴포넌트가 파괴되고 재구성됩니다. 초기 조건 값이 falsy이면, 내부 컨텐츠가 전혀 렌더링되지 않습니다.

    텍스트 또는 여러 엘리먼트를 포함하는 조건부 블록을 나타내기 위해 <template>에 사용할 수도 있습니다.

    이 디렉티브는 조건이 변경될 때, 트랜지션을 트리거합니다.

    v-for와 함께 사용하는 경우, v-if의 우선 순위가 높습니다. 하나의 엘리먼트에 이 두 디렉티브을 함께 사용하는 것은 권장되지 않습니다. 자세한 내용은 리스트 렌더링을 참고하세요.

  • 참고: 조건부 렌더링 - v-if

v-else

v-if 또는 v-else-if 체인에 대한 else입니다.

  • 표현식을 허용하지 않습니다.

  • 세부 사항:

    • 제한사항: 이전 형제 엘리먼트에 v-if 또는 v-else-if가 있어야 합니다.

    • <template>에서 텍스트 또는 여러 엘리먼트를 포함하는 조건부 블록을 나타내는 데 사용할 수 있습니다.

  • 예제

    template
    <div v-if="Math.random() > 0.5">
      이제 나를 볼 수 있어요!
    </div>
    <div v-else>
      아직이에요!
    </div>
  • 참고: 조건부 렌더링 - v-else

v-else-if

v-if에 대한 else if 블록을 나타냅니다. v-else-if는 계속 이어서 사용할 수 있습니다.

  • 요구되는 값: any

  • 세부 사항:

    • 제한사항: 이전 형제 엘리먼트에 v-if 또는 v-else-if가 있어야 합니다.

    • <template>에서 텍스트 또는 여러 엘리먼트를 포함하는 조건부 블록을 나타내는 데 사용할 수 있습니다.

  • 예제

    template
    <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>
      A/B/C 가 아니야!
    </div>
  • 참고: 조건부 렌더링 - v-else-if

v-for

소스 데이터를 기반으로 엘리먼트 또는 템플릿 블록을 여러 번 렌더링합니다.

  • 요구되는 값: Array | Object | number | string | Iterable

  • 세부 사항:

    디렉티브는 반복되는 과정의 현재 값에 별칭을 제공하기 위해, 특수 문법인 alias in expression(표현식 내 별칭)을 사용해야 합니다:

    template
    <div v-for="item in items">
      {{ item.text }}
    </div>

    또한 인덱스(객체에서 사용되는 경우 키)의 별칭을 지정할 수도 있습니다:

    template
    <div v-for="(item, index) in items"></div>
    <div v-for="(value, key) in object"></div>
    <div v-for="(value, name, index) in object"></div>

    v-for의 기본 동작은 엘리먼트를 이동하지 않고 제자리에 패치(patch)하려고 합니다. 강제로 엘리먼트를 재정렬하려면, 특수 속성 key를 사용하여 순서 지정을 위한 힌트를 제공해야 합니다:

    template
    <div v-for="item in items" :key="item.id">
      {{ item.text }}
    </div>

    v-for는 네이티브 Map,Set과 더불어 Iterable Protocol을 구현한 값에서도 작동합니다.

  • 참고:

v-on

엘리먼트에 이벤트 리스너를 연결합니다.

  • 단축 문법: @

  • 요구되는 값: Function | Inline Statement | Object (without argument)

  • 인자: event (선택사항: 객체 문법을 사용하는 경우)

  • 수식어:

    • .stop - event.stopPropagation() 호출.
    • .prevent - event.preventDefault() 호출.
    • .capture - 캡처 모드로 이벤트 등록.
    • .self - 이벤트가 이 엘리먼트에서 전달된 경우에만 트리거 됨.
    • .{keyAlias} - 이벤트가 특정 키에 대해서만 트리거 됨.
    • .once - 이벤트가 한 번만 트리거 됨(일회용처럼).
    • .left - 마우스 왼쪽 버튼으로만 이벤트가 트리거 됨.
    • .right - 마우스 오른쪽 버튼으로만 이벤트가 트리거 됨.
    • .middle - 마우스 중앙(힐 클릭) 버튼으로만 이벤트가 트리거 됨.
    • .passive - { passive: true } 옵션으로 DOM 이벤트를 등록.
  • 세부 사항:

    이벤트 타입은 인자로 표시됩니다. 표현식은 메서드 이름 또는 인라인 명령문이거나, 수식어가 있는 경우 생략될 수 있습니다.

    일반 엘리먼트에 사용되면 네이티브 DOM 이벤트만 수신합니다. 커스텀 엘리먼트 컴포넌트에서 사용되는 경우, 해당 자식 컴포넌트에서 발송(emit)하는 커스텀 이벤트를 수신합니다.

    네이티브 DOM 이벤트를 수신할 때, 메서드의 인자는 네이티브 이벤트 뿐 입니다. 인라인 명령문을 사용하는 경우, 명령문은 특수 속성인 $eventv-on:click="handle('ok', $event)"와 같이 이벤트 객체에 접근할 수 있습니다.

    v-on은 인자 없이 이벤트(키): 리스너(값) 형식의 객체 바인딩도 지원합니다. 수식어는 객체 문법을 사용할 때는 지원하지 않습니다.

  • 예제

    template
    <!-- 메서드 핸들러 -->
    <button v-on:click="doThis"></button>
    
    <!-- 동적 이벤트 -->
    <button v-on:[event]="doThis"></button>
    
    <!-- 인라인 표현식 -->
    <button v-on:click="doThat('hello', $event)"></button>
    
    <!-- 단축 문법 -->
    <button @click="doThis"></button>
    
    <!-- 단축 문법 동적 이벤트 -->
    <button @[event]="doThis"></button>
    
    <!-- 전파 중지 -->
    <button @click.stop="doThis"></button>
    
    <!-- event.preventDefault() 작동 -->
    <button @click.prevent="doThis"></button>
    
    <!-- 표현식 없이 event.preventDefault()만 사용 -->
    <form @submit.prevent></form>
    
    <!-- 수식어 이어서 사용 -->
    <button @click.stop.prevent="doThis"></button>
    
    <!-- 키 별칭을 수식어로 사용 -->
    <input @keyup.enter="onEnter" />
    
    <!-- 클릭 이벤트 단 한 번만 트리거 -->
    <button v-on:click.once="doThis"></button>
    
    <!-- 객체 문법 -->
    <button v-on="{ mousedown: doThis, mouseup: doThat }"></button>

    자식 컴포넌트의 커스텀 이벤트 수신 대기(자식에서 "my-event"가 발생하면 핸들러가 호출됨):

    template
    <MyComponent @my-event="handleThis" />
    
    <!-- 인라인 표현식 -->
    <MyComponent @my-event="handleThis(123, $event)" />
  • 참고:

v-bind

하나 이상의 속성 또는 컴포넌트 prop을 표현식에 동적으로 바인딩합니다.

  • 단축 문법:

    • : 또는 .(.prop 수식어를 사용할 때)
    • 속성(attribute)과 바인딩된 값이 같은 이름을 가질 경우 값을 생략할 수 있음 3.4+
  • 요구되는 값: any (인자 있이) | Object (인자 없이)

  • 인자: attrOrProp (optional)

  • 수식어:

  • 사용법:

    class 또는 style 속성을 바인딩하는 데 사용되는 경우, v-bind는 배열 또는 객체와 같이 값을 추가할 수 있는 타입을 지원합니다. 자세한 내용은 아래 링크된 가이드 섹션을 참고합시다.

    엘리먼트에 바인딩을 설정할 때, Vue는 기본적으로 연산자 검사를 위한 in을 사용하여, 엘리먼트에 프로퍼티로 정의된 키가 있는지 확인합니다. 프로퍼티가 정의되면, Vue는 속성 대신 DOM 프로퍼티로 값을 설정합니다. 이것은 대부분의 경우 작동하지만, .prop 또는 .attr 수식어를 명시적으로 사용하여 이 동작을 재정의할 수 있습니다. 이것은 특히 커스텀 엘리먼트로 작업할 때 필요합니다.

    컴포넌트 prop 바인딩에 사용될 때 prop은 자식 컴포넌트에서 적절하게 선언되어야 합니다.

    인자 없이 사용하는 경우, 속성을 이름-값 쌍으로 포함하는 객체를 바인딩하는 데 사용할 수 있습니다. 이 모드에서 classstyle은 배열 또는 객체를 지원하지 않습니다.

  • 예제

    template
    <!-- 속성 바인딩 -->
    <img v-bind:src="imageSrc" />
    
    <!-- 동적인 속성명 -->
    <button v-bind:[key]="value"></button>
    
    <!-- 단축 문법 -->
    <img :src="imageSrc" />
    
    <!-- 같은 이름 생략 가능 (3.4+), 오른쪽과 같음 :src="src" -->
    <img :src />
    
    <!-- 단축 문법과 동적 속성명 -->
    <button :[key]="value"></button>
    
    <!-- 인라인으로 문자열 결합 -->
    <img :src="'/path/to/images/' + fileName" />
    
    <!-- class 바인딩 -->
    <div :class="{ red: isRed }"></div>
    <div :class="[classA, classB]"></div>
    <div :class="[classA, { classB: isB, classC: isC }]"></div>
    
    <!-- style 바인딩 -->
    <div :style="{ fontSize: size + 'px' }"></div>
    <div :style="[styleObjectA, styleObjectB]"></div>
    
    <!-- 속성을 객체로 바인딩 -->
    <div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
    
    <!-- prop 바인딩. "prop"은 자식 컴포넌트에서 선언되어 있어야 함 -->
    <MyComponent :prop="someThing" />
    
    <!-- 자식 컴포넌트와 공유될 부모 props를 전달 -->
    <MyComponent v-bind="$props" />
    
    <!-- XLink -->
    <svg><a :xlink:special="foo"></a></svg>

    .prop 수식어에는 전용 단축 문법 .가 있습니다:

    template
    <div :someProperty.prop="someObject"></div>
    
    <!-- 위 코드는 아래와 같이 단축할 수 있음 -->
    <div .someProperty="someObject"></div>

    .camel 수식어는 DOM 내 템플릿을 사용할 때, v-bind의 속성명을 카멜라이징(camelizing)할 수 있습니다. 예를 들면, SVG viewBox 속성:

    template
    <svg :view-box.camel="viewBox"></svg>

    문자열 템플릿을 사용하거나 템플릿을 빌드 과정으로 미리 컴파일하는 경우에는 .camel이 필요하지 않습니다.

  • 참고:

v-model

사용자 입력을 받는 폼(form) 엘리먼트 또는 컴포넌트에 양방향 바인딩을 만듭니다.

v-slot

이름이 있는 슬롯 또는 props를 받을 것으로 예상되는 범위형 (Scoped) 슬롯을 나타냅니다.

  • 단축 문법: #

  • 요구되는 값: JavaScript expression that is valid in a function argument position, including support for destructuring. Optional - only needed if expecting props to be passed to the slot.

  • 인자: 슬롯 이름 (선택적, 기본값은 default)

  • 다음으로 제한됨:

    • <template>
    • 컴포넌트 (props를 수신할 기본 슬롯만 있는 경우)
  • 예제

    template
    <!-- 이름이 있는 슬롯 -->
    <BaseLayout>
      <template v-slot:header>
        해더 컨텐츠
      </template>
    
      <template v-slot:default>
        기본 슬롯 컨텐츠
      </template>
    
      <template v-slot:footer>
        푸터 컨텐츠
      </template>
    </BaseLayout>
    
    <!-- props를 수신할 기본 슬롯 -->
    <InfiniteScroll>
      <template v-slot:item="slotProps">
        <div class="item">
          {{ slotProps.item.text }}
        </div>
      </template>
    </InfiniteScroll>
    
    <!-- props를 수신할 기본 슬롯, 분해할당을 사용 -->
    <Mouse v-slot="{ x, y }">
      마우스 위치: {{ x }}, {{ y }}
    </Mouse>
  • 참고:

v-pre

이 엘리먼트와 모든 자식 엘리먼트의 컴파일을 생략합니다.

  • 표현식을 허용하지 않습니다.

  • 세부 사항:

    v-pre가 있는 엘리먼트 내에서 모든 Vue 템플릿 구문은 그대로 유지되고 렌더링됩니다. 가장 일반적인 사용 사례는 이중 중괄호 태그를 표시하는 것입니다.

  • 예제

    template
    <span v-pre>{{ 이곳은 컴파일되지 않습니다. }}</span>

v-once

엘리먼트와 컴포넌트를 한 번만 렌더링하고, 향후 업데이트를 생략합니다.

  • 표현식을 허용하지 않습니다.

  • 세부 사항:

    이후 다시 렌더링할 때 엘리먼트/컴포넌트 및 모든 자식들은 정적 컨텐츠로 처리되어 생략됩니다. 이것은 업데이트 성능을 최적화하는 데 사용할 수 있습니다.

    template
    <!-- 단일 엘리먼트 -->
    <span v-once>절대 바뀌지 않음: {{msg}}</span>
    <!-- 자식이 있는 엘리먼트 -->
    <div v-once>
      <h1>댓글</h1>
      <p>{{msg}}</p>
    </div>
    <!-- 컴포넌트 -->
    <MyComponent v-once :comment="msg"></MyComponent>
    <!-- `v-for` 디렉티브 -->
    <ul>
      <li v-for="i in list" v-once>{{i}}</li>
    </ul>

    3.2부터는 v-memo를 사용하여 무효화 조건으로 템플릿의 일부를 메모화할 수도 있습니다.

  • 참고:

v-memo

  • 요구되는 값: any[]

  • 세부 사항:

    템플릿의 하위 트리를 메모합니다. 엘리먼트와 컴포넌트 모두에 사용할 수 있습니다. 디렉티브는 메모이제이션을 위해 비교할 의존성 값의 고정된 길이의 배열을 요구합니다. 배열의 모든 값이 마지막 렌더링과 같으면 전체 하위 트리에 대한 업데이트를 생략합니다. 예를 들어:

    template
    <div v-memo="[valueA, valueB]">
      ...
    </div>

    컴포넌트가 다시 렌더링될 때 valueAvalueB가 모두 동일하게 유지되면, 이 <div>와 하위 항목에 대한 모든 업데이트를 생략합니다. 사실, 하위 트리의 메모된 복사본을 재사용할 수 있기 때문에 가상 DOM VNode 생성도 생략합니다.

    메모이제이션 배열을 올바르게 지정하는 것이 중요합니다. 그렇지 않으면 실제로 적용되어야 하는 업데이트를 건너뛸 수 있습니다. 빈 의존성 배열(v-memo="[]")이 있는 v-memo는 기능적으로 v-once와 동일합니다.

    v-for과 함께 사용하기

    v-memo는 성능이 중요한 시나리오에서 마이크로 최적화를 위해 제공되는 것으로, 일반적으로 거의 필요하지 않습니다. 이것이 도움이 될 수 있는 가장 일반적인 경우는 큰 리스트(length > 1000)를 v-for로 렌더링할 때입니다:

    template
    <div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
      <p>ID: {{ item.id }} - 선택됨: {{ item.id === selected }}</p>
      <p>...더 많은 자식 노드</p>
    </div>

    컴포넌트의 selected 상태가 변경되면, 대부분의 아이템이 정확히 동일하게 유지되더라도 많은 양의 VNode가 생성됩니다. 여기서 v-memo 사용법은 본질적으로 "아이템의 선택여부가 바뀐 경우에만, 이 아이템을 업데이트하십시오"입니다. 이렇게 하면 영향을 받지 않는 모든 아이템이 이전 VNode를 재사용하고, 차이점 비교를 생략할 수 있습니다. Vue는 아이템의 :key로 자동 추론하므로, 메모 의존성 배열에 item.id를 포함할 필요가 없습니다.

    WARNING

    v-for와 함께 v-memo를 사용할 때, 동일한 엘리먼트에 사용되는지 확인이 필요합니다. v-memov-for 내에서 작동하지 않습니다.

    v-memo는 자식 컴포넌트 업데이트 확인이 최적화되지 않은 특정 엣지 케이스에서 원치 않는 업데이트를 수동으로 방지하기 위해 컴포넌트에 사용할 수도 있습니다. 그러나 필요한 업데이트를 건너뛰지 않도록 올바른 의존성 배열을 지정하는 것은 개발자의 책임입니다.

  • 참고:

v-cloak

준비될 때까지 컴파일되지 않은 템플릿을 숨기는 데 사용됩니다.

  • 표현식을 허용하지 않습니다.

  • 세부 사항:

    이 디렉티브는 빌드 과정이 없는 설정에서만 필요합니다.

    DOM 내 템플릿을 사용할 때, "컴파일되지 않은 템플릿이 순간 보이는 현상"이 있을 수 있습니다. 이러면 사용자는 컴포넌트가 렌더링된 컨텐츠로 대체할 때까지 이중 중괄호 태그를 볼 수 있습니다.

    v-cloak은 연결된 컴포넌트 인스턴스가 마운트될 때까지 엘리먼트에 남아 있습니다. [v-cloak] { display: none }과 같은 CSS 규칙과 결합하여, 컴포넌트가 준비될 때까지 템플릿을 숨기는 데 사용할 수 있습니다.

  • 예제

    css
    [v-cloak] {
      display: none;
    }
    template
    <div v-cloak>
      {{ message }}
    </div>

    <div>는 컴파일이 완료될 때까지 표시되지 않습니다.

빌트인 디렉티브 has loaded