본문 바로가기
front/vue

[vue3 공식문서 번역]Essentials.2.Template Syntax

by juniKang 2022. 4. 21.

뷰는 렌더링된 돔을 근본적인 컴포넌트 인스턴스의 데이터에 선언적으로 바인딩 시킬 수 있는 HTML 기반의 템플릿 구문을 사용한다. 모든 뷰 템플릿은 스펙을 준수한 브라우져와 HTML 파서에 의해 파싱될 수 있는 구문적으로 유효한 HTML 이다.

 

내부적으로, 뷰는 최적화된 자바스크립트 코드로 템플릿을 컴파일 한다. 반응형 시스템과 혼합해서, 뷰는 리렌더할 최소한의 컴포넌트를 똑똑하게 생각해 낼 수 있고, 앱의 상태가 변경되었을 때 최소한의 돔조작을 적용할 수 있다.

 

만약 가상 돔 개념에 친숙하고, 자바스크립트의 원시적인 힘을 선호한다면, 선택적인 JSX 도움으로 템플릿 대신에 직접적인 렌더 함수를 사용할 수 있다. 하지만, 템플릿과 동일한 수준의 컴파일 타임최적화를 즐길수는 없다,

 

택스트 보간법

데이터 바인딩의 가장 기초적인 형태는 "Mustache(콧수염)" 구분을 사용한 텍스트 보간법이다.

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

콧수염 태그는 상호작용하고 있는 컴포넌트 인스턴스의 msg 프로퍼티의 값으로 바뀐다. 또한 msg 프로퍼티 값이 바뀔 때에도 업데이트 된다.

 

원시 HTML

더블 콧수염은. HTML이 아닌 순수한 문자로서의 데이터로 해석한다. 실제 HTML로 해석하기 위해서, v-html 지시어를 사용할 필요가 있다.

<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
Using text interpolation: <span style="color: red">This should be red.</span>
Using v-html directive: This should be red.

여기서 우리는 뭔가 새로운 것에 직면했다. 보고있는 v-html 속성은 지시어(directive)라고 불리운다. 지시어는 뷰에서 제공하는 특별한 속성을 가리키는 v-라는 접두어를 사용하고, 예상햇듯이, 렌더링된 돔에 특별한 반응형 기능을 적용한다. "현재 실행중인 인스턴스를 실시간으로 원시 HTML 문법으로 엘리먼트의 내부 HTML을 유지한다."고 말할 수 있다.

 

span의 내용은 rawHtml 속성의 값으로 변경되고, 순수 HTML로 해석된다. 데이터 바인딩은 무시된다. 템플릿의 부분을 구성하기 위해 v-html을 사용할 수는 없다. 왜냐면, 뷰는 string 기반의 템플릿 엔진이 아니기 때문이다. 대신에, 컨포넌트들은 UI를 재사용하고 구성하기 위한 기초 유닛으로서 사용된다.

 

보안이슈
 웹사이트에서 어떤 HTML을 다이나믹하게 렌더링하는 것은 매우 위험할 수 있다. 왜냐면, 쉽게 XSS vulnerabilities로 읽힐 수 있기 떄문이다. v-html은 유저가 제공할 수 있는 컨텐츠에는 절대 사용하지 말고, 믿을수있는 컨텐츠에만 사용하라.

 

속성(attribute) 바인딩

콧수염들은 HTML 어트리뷰트 안에 사용할 수 없다. 대신에,v-bind 지시어를 사용할 수 있다:

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

v-bind 지시어는 뷰가 div 엘리먼트의 id 어트리뷰트를 컴포넌트의 dynamicId 프로퍼티와 동기화하도록 지시한다. 바인딩 값이 null이거나 undefined이면, 어트리뷰트는 렌더링된 엘리먼트에서 지워질 것이다.

 

- 약칭

v-bind는 매우 자주 쓰여서, v-bind를 가리키는 약칭이 있다.

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

일반적인 HTML과는 약간 다르게 생긴 : 로 시작하는 어트리뷰트는, 어트리뷰트 이름을 나타내는 유효한 문자이며, 모든 뷰를 지원하는 브라우저가 정확하게 구문분석할 수 있다. 또한, 최종적으로 렌더징된 markup에는 나타나지 않는다. 약어는 선택이지만, 나중에 사용법을 좀 더 배우면 당신이 좋아할 것 처럼 보인다.

 

가이드의 뒷부분에서, 코드 예제에서  뷰 개발자를 위한 가장 흔한 사용법으로서 약어를 사용할 것이다.

 

- Boolean 속성

Boolean 어트리뷰트는 엘리먼트에서 존재함으로 true/ false 값을 가리킬 수 있는 속성이다. 예를들면, disabled는 boolean 어트리뷰트를 사용하는 가장 흔한 예중 하나이다.

 

v-bind는 이 경우에는 조금 다르게 동작한다:

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

disabled 어트리뷰트는 isButtonDisabled가 true 일 때만 포함된다. 또한 value가 empty string일때도 포함된다. 값이 빈 문자열인 경우에도 포함되어 <buttons disabled="">와 일관성을 유지한다. 다른 거짓 값의 경우 속성이 생략된다.

 

- 동적으로 바인딩 되는 멀티 어트리뷰트

이렇게 생긴 멀티 어트리뷰트를 나타내는 자바스크립트 객체가 있다면,

const objectOfAttrs = {
  id: 'container',
  class: 'wrapper'
}

아규먼트 없이 v-bind를 사용해서 싱글 엘리먼트에 바인드 할 수 있다.

<div v-bind="objectOfAttrs"></div>

 

자바스크립트 표현식 사용

지금까지는 우리 템플릿에서 단순히 프로퍼티 키로만 바인딩만 했다. 하지만, 뷰는 모든 데이터 바인딩 안에 자바스크립트 표현식의 풀파워를 실제로 지원한다.

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div :id="`list-${id}`"></div>

이 표현식은 현재 컴포넌트 인스턴스의 데이터 범위 안에 자바스크립트로서 평가된다.

 

뷰 템플릿에서, 자바스크립트 표현식은 아래 자리에 사용할 수 있다.

 - 텍스트 보간법 안 (콧수염)

 - 어떤 뷰 지시어(v-로 시작하는 특별한 어트리뷰트)의 어트리뷰트의 값

 

- 오직 표현식으로 사용 가능

각각의 바인딩은 하나의 표현식만 담을 수 있어서, 아래는 동작하지 않는다 :

<!-- this is a statement, not an expression: -->
{{ var a = 1 }}

<!-- flow control won`t work either, use ternary expressions -->
{{ if (ok) { return message } }}

 

- 함수 호출

바인딩 표현식 안에 컴포넌트에서 exposed된 메소드를 호출하는 것은 가능하다.

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

바인딩 표현식 안에서 호출되는 함수는 컴포넌트가 매 업데이트 될 때마다 호출된다. 그래서, 그것들은 데이터가 바뀌거나 실행이 비동기되는 등의 사이드 이펙트를 일으키지 않는다. 

 

- 전역 접근 제한

템플릿 표현식은 샌드박스 되며, 오직 전역의 제한된 목록에만 접근할 수 있다. 목록은 Math나 Date같이 흔히 사용되는 포함된 전역들만 노출한다.

 

전역들은 리스트에 명시적으로 포함되지 않는다. 예를들면, window 프로퍼티에 유저 접근 같은... 템플릿 표현식에서는 접근할 수 없다. 하지만, 추가적인 전역들을 명시적으로 정의함으로서 접근가능하다. 모든 뷰 표현식중 원하는 것을 app.config.globalProperties에 추가함으로서...

 

지시어

지시어는 v- 접두어로 시작하는 특별한 어트리뷰트다. 뷰는 위에 소개한 v-html, v-bind를 포함한 몇개의 내장된 지시어를 제공한다. 

 

지시어 어트리뷰트 값은 하나의 자바스크립트 표현식으로 기대된다.( v-for, v-on, v-slot은 제외한다. 반응형 섹션 다음에 다룬다.) 지시어의 일은 표현식의 값이 변할 때 돔에 업데이트를 반응형으로 적용하는 것이다. 예제로 v-if를 보자:

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

v-if 지시어는 seen의 값이 true/false인지에 따라 p element를 넣거나 빼거나 할 수 있다.

- 아규먼트

몇몇 지시어는 아규먼트를 가질 수 있고, 지시어 이름 다음에 콜론으로 나타낼 수 있다. 예를 들면, v-bind 지시어는 HTML 어트리뷰트에 반응형으로 업데이트하는 것에 사용된다.

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

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

href는 url 표현식의 값으로 엘리먼트의 href 애트리뷰트를 바인드하기 위한 v-bind 지시어를 뜻하는 아규먼트 이다. 약어로, 모든 아규먼트 앞에는( v-bind:같은 )  싱글 캐릭터 : 로 요약할 수 있다. 

 

다른 예는 v-on 지시어다, DOM이벤트를 리슨하는:

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

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

 click 아규먼트는 듣기위한 이벤트 이름입니다. v-on의 약어는 @이며, 상응하는 약어를 가지고 있는 지시어들 중 하나이다. 우리는 좀더 자세히 이벤트 핸들링에 대해서도 얘기할거다.

 

- 동적인 아규먼트

대괄호(square brackets)로 래핑해서 지시 아규먼트에 자바스크립트 표현식을 사용하는 것도 가능하다.

<!--
Note that there are some constraints to the argument expression,
as explained in the "Dynamic Argument Value Constraints" and "Dynamic Argument Syntax Constraints" sections below.
아규먼트 표현식에는 몇가지 제약사항이 있습니다.
아래 설명된 대로...
-->
<a v-bind:[attributeName]="url"> ... </a>

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

attributeName은 자바스크립트 표현식으로 동적으로 평가되고, 이 평가된 값은 아규먼트를 위한 마지막 값으로 사용된다. 예를들면, 만약 컴포넌트 인스턴스가 값이 "href"인 attributeName을 데이터 프로퍼티로 가지고 있다면, v-bind:href와 동등하게 바인딩 된다. 

<template>
  <a :[attributeName]="url">네이버</a>
</template>

<script setup>
const attributeName = "href";
const url = "http://www.naver.com";
</script>

이와 유사하게, 동적인 이벤트 이름으로 핸들러를 바인드하는 동적인 아규먼트도 사용할 수 있다.

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

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

이 예에서, 이벤트이름의 값이 "focus"일 때, v-on:[eventName]은 v-on:focus와 동일할 것이다.

 

- 동적인 아규먼트 값 제한

동적인 아규먼트는 null을 제외하고 string으로 평가되어야 한다. 특별한 값인 null은 바인딩을 명백하게 지울 수 있다. string이 아닌 값은 warning을 발생시킨다.

 

- 동적인 아규먼트 구문 제한

동적인 아규먼트 표현식들은 몇몇 구문제한을 가질수 있다. 왜냐하면, 띄어쓰기나 따옴표같은 특정 문자는 HTML 어트리뷰트 이름으로 유효하지 않다. 예를들면 아래는 유효하지 않다:

<!-- This will trigger a compiler warning. -->
<a :['foo' + bar]="value"> ... </a>

만약 당신이 복잡한 동적인 아규먼트를 넘기길 원한다면, 아마도 computed property를 사용하는게 낫다. 그건 곧 다룰거다.

 

in-DOM 템플릿을 다룰 때는(HTML파일에 직접적으로 적는 템플릿), 브라우져가 소문자로 어트리뷰트 이름을 강제하면서, 대문자로 키값을 이름짓는 것을 피해야 한다.

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

위에예제는 in-DOM 템플릿에서 :[someattr]로 바뀔 것이다. 만약 당신의 컴포넌트에 someattr대신에 someAttr 프로퍼티가 있다면, 당신의 코드는 작동하지 않을 것이다.

 

- 접근지시자

접근지시자는 점으로 나타내는 특별한 접미사이며, 지시어가 특별한 방식으로 바운드 된다는 걸 가리킨다. 예를들면, .prevent 접근지시자는 트리거된 이벤트에 event.preventDefault()를 호출하도록 v-on 지시어에게 지시한다.

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

v-on이나 v-model같은 기능의 접근지시자는 우리가 그 기능들을 다룰 떄 다시 살펴보자.

 

마지막으로, 지시어구문 전체를 시각화한 자료다:

댓글