Development/Vue.js

[Vue.js] Document 따라하기 - Template Syntax

도롱뇽도롱 2022. 5. 24. 18:00
반응형

Vue는 렌더링 된 DOM을 기본 구성 요소 인스턴스의 데이터에 선언적으로 바인딩할 수 있는 HTML 기반 템플릿 구문을 사용한다. 모든 Vue 템플릿은 HTML 파서로 구문 분석할 수 있는 구문적으로 유효한 HTML이다.

 

내부적으로 Vue는 템플릿을 최적화된 JavaScript 코드로 컴파일한다. 반응형 시스템과 결합된 Vue는 앱 상태가 변경될 때 다시 렌더링 할 최소한의 컴포넌트를 파악하여 DOM 조작을 최소화한다.

 

가상 DOM 개념에 익숙하고 JavaScript의 원시 기능을 선호하는 경우 JSX 지원 옵션을 사용하여 템플릿 대신 렌더링 기능을 직접 작성할 수도 있다.

Text Interpolation

데이터 바인딩의 가장 기본적인 형태는 "Mustache" 구문을 이용한 텍스트 보간이다.

<span>Message: {{ msg }}</span>

Mustache 태그는 해당 구성 요소 인스턴스의 msg 속성 값으로 대체되며 msg 속성의 값이 변경될 때마다 업데이트된다.

Text Interpolation
Text Interpolation
Text Interpolation

TextInterpolation.vue를 생성하여 msg 속성을 불러오도록 작성하고 Exercise01.vue에서 TextInterpoliation component를 불러옴과 동시에 msg 속성의 값을 지정해주면 실행된 페이지에서 "This is for test"라는 문구를 확인할 수 있다. 추가로 개발자도구의 Vue 탭에서 TextInterpolation의 msg 값으로 어떤 값이 들어왔는지 확인해 볼 수 있다.

 

Raw HTML

이중 mustache(중괄호)는 데이터를 HTML이 아닌 일반 텍스트로 해석한다. 일반 텍스트가 아닌 HTML로 출력하기 위해서는 v-html 디렉티브를 사용해줘야 한다.

<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

Raw HTML
Raw HTML

여기서 사용되는 v-html 속성은 디렉티브라고 하는데 Vue에서 제공하는 특수 속성임을 나타내기 위해 접두사 v-가 붙게 되고 렌더링 된 DOM에 특수한 반응적 동작을 적용한다. 이는 현재 활성 인스턴스의 rawHTML 속성을 사용하여 이 요소의 inner HTML을 최신 상태로 유지하도록 명시한 것이다.

<span>의 컨텐츠는 rawHTML 속성 값으로 대체되며 데이터 바인딩이 무시되고 일반 HTML로 해석된다. Vue는 문자열 기반 템플릿 엔진이 아니기 때문에 v-html을 사용하여 템플릿 부분을 작성할 수는 없으나 컴포넌트의 경우 UI 재사용 및 구성을 위한 기본 단위로 사용되는 것을 추천한다.

웹사이트에서 임의의 HTML을 동적으로 렌더링 한다면 XSS 취약점이 쉽게 발생할 수 있기에 신뢰할 수 있는 컨텐츠에만 v-html을 사용하고 사용자 제공 컨텐츠에서는 사용하지 않는 것을 권장한다.

 

Attribute Bindings

이중 mustache(중괄호)는 HTML attribute 내에서 사용될 수 없으며 v-bind 디렉티브로 대체될 수 있다.

<div v-bind:id="dynamicId"></div>

Attribute Bindings
Attribute Bindings

v-bind 디렉티브는 element의 id 속성을 component의 dynamicId 속성과 동기화된 상태로 유지하도록 Vue에 지시한다. 바인딩 된 값이 null이거나 undefined인 경우 속성은 렌더링 된 element에서 제거된다.

 

Shorthand

v-bind는 Vue에서 매우 일반적으로 사용되기 때문에 단축 구문이 별도로 존재한다.

<div :id="dynamicId"></div>

Shorthand

:로 시작하는 속성은 일반 HTML과 약간 다르게 보일 수 있지만 실제 HTML에 유효한 문자이며 Vue를 지원하는 모든 브라우저에서 올바른 구문 분석이 가능하다. 최종으로 렌더링 된 마크업에서는 표시되지 않는다.

 

Boolean Attributes

Boolean 속성은 element에 존재함으로써 true/false 값을 나타낼 수 있는 속성으로 disabled는 가장 일반적으로 사용되는 bool 속성이다.

이 경우 v-bind는 약간 다르게 작동한다.

<button :disabled="isButtonDisabled">Button</button>

Boolean Attributes
Boolean Attributes
Boolean Attributes

isButtonDisabled의 값이 true이면 button의 disabled 속성이 포함되고 false의 경우 disabled 속성이 포함되지 않는 것을 확인할 수 있다.

 

Dynamically Binding Multiple Attributes

여러 속성을 나타내는 JavaScript 객체가 있는 경우 별도의 인수 없이 v-bind를 사용하여 element에 바인딩할 수 있다.

data() {
  return {
    objectOfAttrs: {
      id: 'container',
      class: 'wrapper'
    }
  }
}
<div v-bind="objectOfAttrs"></div>

 

Dynamically Binding Multiple Attributes
Dynamically Binding Multiple Attributes

 

Using JavaScript Expressions

지금까지 템플릿의 간단한 속성 키에만 바인딩을 해보았지만 Vue는 모든 데이터 바인딩 내에서 JavaScript 표현식의 모든 기능을 지원한다.

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div :id="`list-${id}`"></div>

이러한 표현식은 현재 component 인스턴스의 데이터 범위 내에서 JavaScript로 계산된다.

 

Vue 템플릿에서 JavaScript 표현식은 아래의 위치에서 사용할 수 있다.

  • Text Interpolations(텍스트 보간) 내에서
  • 모든 Vue 디렉티브의 속성 값에서(v-로 시작하는 특수 속성)

Expressions Only

각 바인딩은 하나의 단일 표현식만 포함할 수 있다.

<!-- 표현식이 아닌 명령문이기에 작동하지 않음 -->
{{ var a = 1 }}

<!-- 흐름 제어도 작동하지 않기 때문에 삼항 연산자를 사용하여야 함 -->
{{ if (ok) { return message } }}

 

Calling Functions

바인딩 표현식 내에서 component-exposed 메서드를 호출할 수 있다.

<span :title="toTitleDate(date)">
  {{ formatDate(date) }}
</span>

바인딩 표현식 내에서 호출되는 함수는 component가 업데이트될 때마다 호출되기에 데이터 변경 또는 비동기 작업 트리거와 같이 사이드 이펙트를 초래하는 것이 없어야 한다.

Calling Functions
Calling Functions

 

Restricted Globals Access

템플릿 표현식은 샌드박스 처리되며 Math 및 Date와 같이 일반적으로 사용되는 기본 제공 전역에만 접근할 수 있다.

https://github.com/vuejs/core/blob/main/packages/shared/src/globalsWhitelist.ts#L3

위 링크에 포함되지 않은 전역은 템플릿 표현식에서 액세스 할 수 없지만 app.config.globalProperties에 추가하여 모든 Vue 표현식에 대한 추가 전역을 명시적으로 정의할 수 있다.

 

Directives

디렉티브(지시문)는 v-접두사가 있는 특수 속성으로 Vue는 앞에서 언급하였던 v-html, v-bind를 포함하여 여러 디렉티브를 제공한다.

디렉티브 속성 값은 단일 JavaScript 표현식이어야 한다. v-for, v-on, v-slot은 예외로 추후에 설명된다. 디렉티브의 역할은 표현식의 값이 변경될 때 DOM에 반응적으로 업데이트를 적용하는 것이다.

<p v-if="seen">Now you see me</p>​

위의 경우 v-if 디렉티브는 제공된 표현식(seen)의 값을 기반으로 <p> element를 추가하거나 제거한다.

Directives
Directives

 

Arguments

일부 디렉티브는 디렉티브명 뒤에 콜론(:)으로 표시되는 전달 인자를 사용할 수 있다. v-bind 디렉티브는 HTML 속성을 반응적으로 업데이트하는 데 사용된다.

<a v-bind:href="url"> ... </a>

<!-- shorthand -->
<a :href="url"> ... </a>

Arguments
Arguments

여기서 href는 전달 인자로 v-bind 디렉티브가 url의 값을 element의 href 속성에 바인딩하도록 지시한다. v-bind와 같이 전달인자 앞에 붙는 것은 :으로 사용할 수 있다.

 

v-on은 DOM 이벤트를 수신하는 디렉티브이다.

<a v-on:click="doSomething"> ... </a>

<!-- shorthand -->
<a @click="doSomething"> ... </a>

Arguments
Arguments

여기서의 전달 인자는 수신할 이벤트의 이름이다. v-on의 경우 @로 사용할 수 있다.

 

Dynamic Arguments

JavaScript 표현식을 대괄호로 감싸 디렉티브 전달 인자로 사용할 수 있다.

<a v-bind:[attributeName]="url"> ... </a>

<!-- shorthand -->
<a :[attributeName]="url"> ... </a>

여기에서 attributeName은 JavaScript 표현식으로 동적 변환되며, 변환된 값은 전달 인자의 최종 값으로 사용된다. Component 인스턴스에 값이 href인 데이터 속성 attributeName이 있다면 이는 v-bind:href와 동일하다.

Dynamic Arguments
Dynamic Arguments

 

마찬가지로 동적 전달 인자를 이용하여 핸들러를 동적 이벤트명에 바인딩할 수 있다.

<a v-on:[eventName]="doSomething"> ... </a>

<!-- shorthand -->
<a @[eventName]="doSomething">

Dynamic Arguments
Dynamic Arguments

여기서 eventName의 값이 "focus"일 경우 v-on:[eventName]은 v-on:focus와 동일하다.

 

Dynamic Argument Value Constraints

동적 전달 인수 값에는 제약조건이 있는데, 동적 전달 인수는 null을 제외하고 string으로 변환되어야 한다. 특수 값인 null을 사용하면 명시적으로 바인딩을 제거할 수 있다. string이 아닌 다른 값은 경고를 출력한다.

 

Dynamic Argument Syntax Constraints

동적 전달 인수 형식에는 일부 제약이 있다. 동적 전달인수 표현식에는 공백 및 따옴표와 같은 특정 문자가 HTML 속성명 내에서 유효하지 않기 때문인데, 아래는 유효하지 않은 동적 전달인수 표현식의 예다.

<!-- 컴파일러 경고를 야기한다. -->
<a :['foo' + bar]="value"> ... </a>

복잡한 표현식은 추후에 다뤄질 computed 속성을 사용하는 것이 더 나을 것이다.

 

in-DOM 템플릿(HTML 파일에 직접 작성된 템플릿)을 사용할 때 브라우저가 속성명을 소문자로 강제 변환하기에 대문자를 넣지 않는 것이 좋다.

<a :[someAttr]="value"> ... </a>

in-DOM 템플릿에서 someAttr은 someattr로 변환되며 인스턴스에 "someattr"이 없는 경우 코드는 동작하지 않는다.

 

Modifiers

수식어는 점으로 표시되는 특수 접미사로 디렉티브가 특별한 방식으로 바인딩되어야 함을 나타낸다. 예를 들어, .prevent 수식어는 v-on 디렉티브에 트리거 된 이벤트에서 event.preventDefault()를 호출하도록 지시한다.

<form @submit.prevent="onSubmit">...</form>

v-on과 v-model에 대한 수식어의 다른 예는 추후에 언급된다.

 

full directive syntax visualized

 

관련 Repo

https://github.com/galaxyuliana/VueExercises/tree/master/first-vue-project/src/components/Exercise/01

 

참고자료

https://vuejs.org/guide/essentials/template-syntax.html

반응형