이재웅
v-for
디렉티브는 배열, 혹은 객체를 기반으로 리스트 렌더링을 가능하게 한다.기본적인 문법은 아래와 같으며, in을 of 로 바꾸어도 상관 없다.
<li v-for=”(item [, index]) in items”>somValue</li>
객체 리스트 렌더링은 배열과 문법이 달라지며, 순서는
Object.key()
의 나열 순서를 따라간다.<li v-for=”(value [, key ] [, index]) in object”>someValue</li>
또한 리스트의 상태가 변할 때, 효율적인 렌더링을 위해
key
값을 이용하며, key
는 String
혹은 Number
타입만 사용하도록 한다.간단한 list 상태 조작 예제
- HTML
<html> <head> <title>List Test</title> </head> <body> <div class="list-container"> <ul id="array-list"> <li v-for="fruit in fruits"> {{ fruit.name }} </li> </ul> <input v-model.trim="fruitName" /> <button @click="addFruit">Add Fruit!</button> <button @click="deleteLastFruit">Delete Fruit!</button> </div> <script src="https://unpkg.com/vue@next"></script> <script src="/main.js" type="module"></script> </body> </html>
- JS
const FruitList = { data() { return { fruitName: '', fruits: [ { name: 'apple' }, { name: 'banana' }, { name: 'grape' }, { name: 'lime' }, { name: 'lemon' }, ] } }, methods: { addFruit() { const { fruits, fruitName } = this; if (fruitName.length > 0) { fruits.push({ name: fruitName }); this.fruitName = ''; } }, deleteLastFruit() { const { fruits } = this; this.fruits = fruits.slice(0, fruits.length - 1); } } } Vue.createApp(FruitList).mount('.list-container');
메서드를 이용해 직접 상태를 변경하거나, 배열을 교체하지 않고 아래처럼
computed
속성을 이용해서 렌더링 하는 것도 가능하다.computed
를 이용해 l로 시작하는 list만 렌더링 하는 예제- HTML
<html> <head> <title>List Test</title> </head> <body> <div class="list-container"> <ul id="array-list"> <li v-for="fruit in filterFruits"> {{ fruit.name }} </li> </ul> <input v-model.trim="fruitName" /> <button @click="addFruit">Add Fruit!</button> <button @click="deleteLastFruit">Delete Fruit!</button> </div> <script src="https://unpkg.com/vue@next"></script> <script src="/main.js" type="module"></script> </body> </html>
- JS
const FruitList = { data() { return { fruitName: '', fruits: [ { name: 'apple' }, { name: 'banana' }, { name: 'grape' }, { name: 'lime' }, { name: 'lemon' }, ] } }, methods: { addFruit() { const { fruits, fruitName } = this; if (fruitName.length > 0) { fruits.push({ name: fruitName }); this.fruitName = ''; } }, deleteLastFruit() { const { fruits } = this; this.fruits = fruits.slice(0, fruits.length - 1); } }, computed: { filterFruits() { return this.fruits.filter(fruit => fruit.name.startsWith('l')); } } } Vue.createApp(FruitList).mount('.list-container');
그 외에도
items
에 정수를 넣어 range
렌더링 또한 가능하며, template
속성에 v-for
디렉티브를 설정해서 ItemComponent
를 추상화 시키지 않고 렌더링 하는 것도 가능하다.또한
v-if
와 v-for
디렉티브를 동시에 사용하면 v-if
가 우선하므로, v-if
의 데이터에 따라 list가 아예 렌더링 되지 않을 수 있으니 래핑하는 Tag를 만들어서 따로 사용하도록 하자.template
태그와v-for
디렉티브를 이용해서 더 작은 컴포넌트 단위로 추상화 하는 과정을 줄일 수 있다는 점이 장점처럼 느껴졌습니다.
- 규범 님이 준비해주신 예제를 통해 실제로
API
호출을 통해 데이터를 받았을 때, 사용하기 편한 데이터로 가공하는 방법을 알 수 있어서 좋았던 것 같습니다.
장규범

<template> <div class="about-page"> <HeaderComponents/> <main> <div class="w3-container"> <h1>This is an about page</h1> <ul class="item-title"> <li v-for="items in AboutInfo" :key="items"> <span v-for="item in items" :key="item"> {{ item }} </span> </li> </ul> </div> </main> </div> </template> <script> import HeaderComponents from "../components/Header.vue"; export default { name: "AboutPage", components: { HeaderComponents, }, data() { return { AboutInfo: [{ title: 'JOACE', description: '하고 싶은 것을 전부 올릴 웹페이지입니다!', items: [ { itemTitle: 'Virtual Reality', itemDescription: '완전 몰입형 가상현실 기획' }, { itemTitle: 'Augmented Reality', itemDescription: '자비스 같은 인공지능 IOT 서비스 제공' }, { itemTitle: '논문 연구', itemDescription: '영상처리, 컴퓨터 비전, 그래픽스 논문 연구' } ] }] } }, methods: { isDataExist() { if (this.items) { return true; } return false; }, } }; </script> <style scoped> </style>
- 공식문서만 봤을 때는 쉽게쉽게 넘어갔습니다. 리스트 렌더링에 대해서 공부를 한 것에 대해서 간단하게 구현을 해봤는데 임시로 만든 예제에서 itemTitle을 제대로 뽑아내는 것에 어려움을 조금 겪었습니다. 이 방안에 대해 논의해보면서 조금 깊게 생각해볼 수 있는 기회가 된 것 같습니다.
팽건우
같이 새로운 지식에 대해 이야기를 나누고 문제에 대해 같이 고민을 하니 혼자서 공부할 때보다 부족한 점을 많이 메꿔주는 것 같습니다.
다음에는 좀 더 정리를 해서 도움이 될 수 있게 하겠습니다. 🙂
홍정기
처음 공부했을 때 보다는 뷰에 조금 더 익숙해진 것 같다. 끝!