컴포넌트 데이터에 따라 링크와 이름이 나타나는 카테고리 태그를 만들었습니다. 하지만 카테고리를 추가할 때마다 태그 내용을 추가하거나 수정해야 하는 불편함이 있습니다. 이러한 문제를 해결하기 위해, v-for
디렉티브를 사용하여 배열이나 객체로 반복적인 태그를 만들 수 있습니다.
v-for
v-for는 배열이나 객체와 같은 반복 가능한 값들을 기반으로 태그를 여러 개 그릴 수 있도록 도와줍니다.
문법
Javascript에서는 배열이나 객체를 반복하기 위해 다음과 같은 문법을 사용합니다.
- 배열 :
for (let 변수 of 배열) { }
- 객체 :
for (let 키 in 객체) { }
v-for의 경우도 크게 다르지 않습니다.
<!-- 배열 -->
<tag v-for="변수 of 배열"></tag>
<!-- 객체 -->
<tag v-for="키 in 객체"></tag>
v-for에서는of
와in
을 특별히 구분하지 않습니다. 배열에in
을 쓰거나 객체에of
를 써도 됩니다. 하지만 개발자들은 객체인지 배열인지 명확하게 구분할 수 있도록 배열에는of
를, 객체에는in
을 사용하는 것이 좋습니다.
우리가 만들었던 categories: ["HTML", "CSS", "Javascript"]
값을 사용해봅시다.
<a v-for="c of categories"></a>
그러면 다음과 같이 렌더링 됩니다.
<a></a>
<a></a>
<a></a>
내용이나 속성은 전혀 들어가지 않았습니다. 왜냐하면 우리가 변수로 받은 c
값을 아직 활용하지 않았기 때문입니다.
v-bind와 콧수염 문법
변수 c
에는 차례로 HTML, CSS, JavaScript 값이 들어갑니다. 그리고 이전에 배웠던 v-bind
와 콧수염 문법을 적용할 수 있습니다.
<a v-for="c of categories" :href="'/' + c.toLowerCase()" >{{ c }}</a>
그러면 다음과 같이 렌더링됩니다.
<a href="/html">HTML</a>
<a href="/css">CSS</a>
<a href="/javascript">Javascript</a>
생략가능한 값과 인덱스
가끔 for문을 사용하다보면 index 값을 사용하고 싶을 수 있습니다. v-for는 사실 반복 변수 뿐만 아니라 인덱스(index) 값도 포함한채로 전달해줍니다. 객체의 경우 키 뿐만 아니라 값도 같이 전달해줍니다.
<!-- 배열 -->
<tag v-for="(변수, 인덱스) of 배열"></tag>
<!-- 객체 -->
<tag v-for="(키, 값, 인덱스) in 객체"></tag>
이전 예시에서 이렇게 값이나 인덱스를 쓰지 않은 것은 뒤에서부터 생략이 가능하기 때문입니다. 생략해서 하나만 남으면 괄호(()
)를 제거할 수 있습니다.
<!-- 배열 -->
<tag v-for="(변수, 인덱스) of 배열"></tag>
<!-- 인덱스 생략 -->
<tag v-for="변수 of 배열"></tag>
<!-- 객체 -->
<tag v-for="(키, 값, 인덱스) in 객체"></tag>
<!-- 인덱스 생략 -->
<tag v-for="(키, 값) in 객체"></tag>
<!-- 값 생략 -->
<tag v-for="키 in 객체"></tag>
이렇게 가져온 값도 변수처럼 사용하면 됩니다. 예를 들어 인덱스를 수염 문법에 넣어보겠습니다.
<a
v-for="(c, i) of categories"
:href="'/' + c.toLowerCase()"
>
{{ i }}. {{ c }}
</a>
다음과 같이 렌더링됩니다.
<a href="/html">0. HTML</a>
<a href="/css">1. CSS</a>
<a href="/javascript">2. Javascript</a>
index는 0부터 시작하기에 0, 1, 2 가 차례로 들어갔습니다.
v-for의 짝궁 key
마지막으로 v-for
문법을 사용할 때 key
속성을 같이 넣어주어야 합니다. key
는 태그들 간에 구분을 하기 위한 id
와 같은 역할을 합니다. 이 속성에는 문자열이나 숫자와 같은 원시 타입(primitive type)을 사용해야 하며, 객체나 함수와 같은 값을 사용하면 안 됩니다.
이 속성은 반복되는 태그마다 다르게 들어가야 하기 때문에 주로 변수를 사용합니다.
<a v-for="c of categories" :key="c">{{ c }}</a>
key 값을 안 넣어도 동작은 합니다. 하지만 이후에 배열이나 객체의 값을 추가, 제거 하는 등의 조작을 하게 되면(특히 컴포넌트나 form을 같이 사용할 때) 엉뚱하게 렌더링될 수 있습니다. 또한 성능에도 영향을 미치는 요인이기 때문에 꼭 넣는 것이 좋습니다.
메뉴 코드 정리하기
이제 v-for
를 익혔으니 이전의 코드를 수정해보겠습니다. 우선 a 태그를 반복해야하니 v-for
를 써야합니다.
<nav class="menu">
<a
v-for="c of categories"
class="category"
>
</a>
</nav>
그리고 key
값도 잊지말고 꼭 넣어야합니다.
<nav class="menu">
<a
v-for="c of categories"
:key="c"
class="category"
>
</a>
</nav>
콧수염 문법으로 이 카테고리 값도 채워줍니다.
<nav class="menu">
<a
v-for="c of categories"
:key="c"
class="category"
>
{{ c }}
</a>
</nav>
마지막으로 href
속성을 v-bind
를 통해 넣어줍니다.
<nav class="menu">
<a
v-for="c of categories"
:key="c"
:href="'/' + c.toLowerCase()"
class="category"
>
{{ c }}
</a>
</nav>
조금 복잡해 보이지만, 카테고리를 여러 개 추가해도 수정할 것이 없습니다. URL을 바꾼다고 해도 한 번만 수정하면 됩니다. 이제 메뉴바가 완성되었으니 아래에 글 목록을 만들어보겠습니다.