v-for
v-for 디렉티브를 사용해서 배열을 기반으로 리스트를 렌더링 할 수 있다.
기본 사용방법
<ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li> </ul>
|
var example1 = new Vue({ el: '#example-1', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
|
v-for 디렉티브는 item in items 의 형태의 문법을 사용합니다.
items는 원본 데이터 배열이고, item은 배열 엘리먼트의 별칭입니다.
결과:
v-for 블록 안에는 부모속성에 대한 모든 권한이 있다.
v-for은 현재 항목에 대한 인덱스를 2번째 전달인자로 받는다.
<ul id="example-2"> <li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul>
|
var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } })
|
결과:
- Parent - 0 - Foo
- Parent - 1 - Bar
in 대신 of를 사용도 가능하다.
v-for
템플릿
v-if 처럼 <template>을 사용이 가능하다.
<ul> <template v-for="item in items"> <li>{{ item.msg }}</li> <li class="divider"></li> </template> </ul>
|
객체의 속성도 반복이 가능합니다.
<ul> <template v-for="item in items"> <li>{{ item.msg }}</li> <li class="divider"></li> </template> </ul>
|
new Vue({ el: '#repeat-object', data: { object: { firstName: 'John', lastName: 'Doe', age: 30 } } })
|
결과:
키를 두번째 전달인자로 사용이 가능하다.
<div v-for="(value, key) in object"> {{ key }} : {{ value }} </div>
|
인덱스도 제공이 가능하다.
<div v-for="(value, key, index) in object">
{{ index }}. {{ key }} : {{ value }}
</div>
객체를 반복할 때 순서는 Object.keys()
의 키 나열 순서에 따라 결정됩니다. 이 순서는 JavaScript 엔진 구현간에 일관적이지는 않습니다.
Range v-for
단순한 for문도 사용이 가능하다.
<div> <span v-for="n in 10">{{ n }}</span> </div>
|
컴포넌트와 v-for
<my-component v-for="item in items" :key="item.id"></my-component>
|
2.2.0버전 이후로, v-for
를 사용할 때 key
가 반드시 있어야 합니다.
간단한 할일을 하는 목록을 만드는 예제다.
<div id="todo-list-example"> <input v-model="newTodoText" v-on:keyup.enter="addNewTodo" placeholder="Add a todo" > <ul> <li is="todo-item" v-for="(todo, index) in todos" v-bind:key="todo" v-bind:title="todo" v-on:remove="todos.splice(index, 1)" ></li> </ul> </div>
|
Vue.component('todo-item', { template: ` <li> {{ title }} <button v-on:click="$emit('remove')">X</button> </li> `, props: ['title'] }) new Vue({ el: '#todo-list-example', data: { newTodoText: '', todos: [ 'Do the dishes', 'Take out the trash', 'Mow the lawn' ] }, methods: { addNewTodo: function () { this.todos.push(this.newTodoText) this.newTodoText = '' } } })
|
리스트 add하는 작동 순서
input v-model을 사용해 newTodoText값을 바인딩한다.
엔터를 하면 addNewTodo 메소드를 실행한다.
그러면 data속성 todos배열에 push로 값이 추가된다.
그러면 DOM이 업데이트 되면서 li가 출력된다.
v-for
와 v-if
같은 노드에서 사용될 때, v-for이 더 높은 우선순위로 실행된다.
<li v-for="todo in todos" v-if="!todo.isComplete"> {{ todo }} </li>
|
key
Vue가 각 노드를 재정렬하고, 추적하기 위해 사용한다.
고유값이다.
동적 바인딩을 해야한다. v-bind사용
<div v-for="item in items" :key="item.id"> </div>
|
배열 변경 감지
변이 메소드
Vue는 감시중인 배열의 변이 메소드를 래핑해 뷰 갱신을 트리거한다.
래핑된 메소드 리스트
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
example1.items.push({ message: 'Baz' })
이런식으로 사용이 가능하다.
배열 대체
변이된 메소드는 호출된 원본 배열을 변형시킨다.
변형을 하지 않고 새로 생성하는 방법도 있다.
filter()
, concat()
와 slice()
example1.items = example1.items.filter(function (item) { return item.message.match(/Foo/) })
|
DOM을 다시 렌더링 하지않고 변경부분만 처리하는거 같다.
주의 사항
JavaScript의 제한으로 인해 Vue는 배열에 대해 다음과 같은 변경 사항을 감지할 수 없습니다.
- 인덱스로 배열에 있는 항목을 직접 설정하는 경우, 예:
vm.items[indexOfItem] = newValue
- 배열 길이를 수정하는 경우, 예:
vm.items.length = newLength
항목을 직접 설정하려면 다음과 같이 사용해야한다.
Vue.set(example1.items, indexOfItem, newValue)
|
example1.items.splice(indexOfItem, 1, newValue)
|
배열 길이를 수정하려면
example1.items.splice(newLength)
|
필터링 / 정렬 된 결과 표시하기
원본 데이터를 수정하지 않고, 필터링된 결과를 리턴해야 할 경우가 있다.
<li v-for="n in evenNumbers">{{ n }}</li>
|
data: { numbers: [ 1, 2, 3, 4, 5 ] }, computed: { evenNumbers: function () { return this.numbers.filter(function (number) { return number % 2 === 0 }) } }
|
계산된 속성을 사용할 수 없을 경우에는 다음과 같이 사용한다.
<li v-for="n in even(numbers)">{{ n }}</li>
|
data: { numbers: [ 1, 2, 3, 4, 5 ] }, methods: { even: function (numbers) { return numbers.filter(function (number) { return number % 2 === 0 }) } }
|