디렉티브는
v-
접두사가 있는 특수 속성이다. 그대로 직역하면 '지시'를 뜻한다.
즉, 디렉티브는 기능상에서 중요한 역할인 컴포넌트(또는 DOM요소)에게 "~~~하게 작동할 것"을 지시해주는 지시문을 말한다.
Vue는 여러가지 내장 디렉티브를 제공한다.
이전 포스팅들에서도 썼던 이미 익숙한 디렉티브들도 보인다.
천천히 디렉티브들을 살펴보자.
디렉티브는 다음과 같이 구성되어 있다.
v-
접두사가 있는 특수 속성으로 디렉티브의 값(value)이 변경될 때 특정 효과를 반응적으로 DOM에 적용하는 것을 말한다.v-bind
디렉티브는 반응적으로 HTML 속성을 갱신하는 데 사용한다.엘리먼트의
textContent
를 업데이트 한다.
- 요구값: String
<span v-text="msg"></span> <!-- 같은 방법 --> <span> {{ msg }} </span>
v-text
는 html이 아닌 문자열로 인식한다.
변수에 <p>Hello</p>
를 넣고 v-text
를 사용했을 때, 'Hello'만 출력되는 것이 아닌 <p>
태그를 문자열 그대로 인식하여 <p>Hello</p>
가 출력된다.
이 디렉티브는 연결된 컴포넌트 인스턴스가 컴파일을 완료 할 때까지 엘리먼트에 남아있는다. 컴파일이 완료된 후에는 자동으로 삭제된다.
<div v-cloak> {{ message }} </div>
쉬운 예제를 하나 생각해보자.
<div id="app">
<p>{{ messge }} </p>
</div>
<script setup>
const messsage = ref();
const App = () => {
message.value = "안녕하세요";
}
//3초후에 로딩
setTimeout(()=> {
Vue.createApp(App).mount('#app');
}, 300)
</script>
3초 전까지는 {{ message }}
가 그대로 출력된 후, 3초 후에 데이터가 바인딩 되어 안녕하세요
가 출력될 것이다.
클라이언트 입장에서 {{ message }}
가 그대로 노출된 후, 데이터가 변경되는 것은 꽤나 불편할 것이다.
이럴 때 쓰는 것이 v-cloak
이다.
<p v-cloak> {{ message }} </p>
v-cloak
는 컴파일이 완료될 때까지 <p v-cloak>
으로 남아있다가 컴파일이 완료되면 삭제되어 <p>
가 된다.
즉, v-cloak
디렉티브를 사용 후 [v-cloak] { display : none } 과 같은 CSS를 주면 컴파일이 완료될때까지 {{ message }}
의 노출을 막을 수 있다.
컴파일이 완료될 때까지 <p v-cloak>
이므로 display:none상태였다가 컴파일이 완료된 후 자동 삭제되어 CSS 적용이 해제된다.
위의 예제에 적용하면 3초동안 {{ message }}
가 뜨지 않고 display:none상태로 있다가 3초 후 컴파일이 완료되며 안녕하세요
만 뜨는 것이다.
엘리먼트와 컴포넌트를 한번(once)만 렌더링한다. 이후에 재렌더링 할 때 엘리먼트/컴포넌트 및 모든 하위 엘리먼트는 정적 컨텐츠로 처리되고 건너 뛴다. 업데이트 성능을 최적화하는데 사용할 수 있다.
<p v-once> 유지 메세지 : {{ message }} </p>
한번 렌더링 된 후에는 message의 데이터가 변경돼도 그대로 유지된다.
즉, 처음 렌더링 된 후 캐싱되도록 지정하는 것이다.
이러한 특성을 사용하여 정적 콘텐츠를 지정할 수 있다.
쉬운 예를 하나 생각해보자.
<template>
<p v-once>{{ message }}</p>
<p>{{ message }}</p>
<button @click="change()"> 버튼 </button>
</template>
<script setup>
const message = ref("안녕하세요.");
const change = () => {
message.value = "반갑습니다.";
}
</script>
1) 버튼 클릭 전
안녕하세요.
안녕하세요.
2) 버튼 클릭 후
안녕하세요.
반갑습니다.
v-once
디렉티브가 걸린 {{ message }}는 데이터 변경이 적용되지 않았다.
v-once
디렉티브가 걸리면, 데이터가 변경되어도 처음 렌더링 된 것이 유지된다.
v-once
는 남용하지 않는 것이 좋다. 이는 렌더링할 정적 컨텐츠가 굉장히 많은 경우에 편리하게 사용할 수는 있지만, 느리게 렌더링 되는 것을 인지하지 못할 정도라면 필수적이지 않다.
또한, 이런 방식은 v-once
에 친숙하지 않은 개발자들에게 템플릿 업데이트 문제에 대해 많은 시간을 소비하게 만들 수 있다.
(3.2버전부터 사용 가능)
v-once와 비슷하게 리렌더링을 방지한다. 다만, 반응형 데이터가 변경되면 업데이트 되도록 설정할 수 있다.
<div v-memo="[valueA, valueB]"> ... </div>
valueA와 valueB가 변경되지 않으면 전체 하위 트리에 대한 업데이트를 생략한다. valueA와 valueB가 변경된 경우에만 업데이트 된다.
(v-memo="[]"의 경우 기능적으로 v-once와 동일하다.)
동일한 입력이 주어졌을 경우 재평가하지 않고 함수가 동일한 값을 반환하도록 하여 성능을 위해 프로그램을 최적화하는 기술이라고 할 수 있다.
공식문서에서는 v-for문에서 반복 횟수가 1000회가 넘을 때(length > 1000) v-memo를 사용하면 아주 좋다고 설명하고 있다.
<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
<p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p>
<p>...more child nodes</p>
</div>
여기서 v-memo
는 "selected가 변경된 경우에만 업데이트 하십시오." 라는 의미이다.
즉, selected의 영향을 받지 않는 항목들이 이전 VNode를 재사용하고 diffing(비교)을 완전히 건너뛸 수 있다.
자식들의 최신 업데이트를 방지하기 위해 구성요소에 사용할 수 있는 것이다.
글 잘읽었습니다. 저도 개발자 준비중인데 같이 교류하면서 해요!