-
[가이드] 리스트 렌더링 - 필수요소 | VueFront-end/Vue.js 2020. 8. 13. 13:16반응형
v-for로 배열을 요소에 매핑
v-for 지시문을 사용하여 배열을 기반으로 목록을 렌더링할 수 있습니다. v-for 지시문을 사용하려면 item in items 형식의 특수 구문이 필요합니다. 여기서 items은 소스 데이터 배열이고 item은 반복될 배열 요소의 별칭입니다.
<ul id="ex1"> <li v-for="item in items" :key="item.message"> {{ item.message }} </li> </ul> <script> var example1 = new Vue({ el: '#ex1', data: { items: [ { message: 'Foo' }, { message: 'Bar' } ] } }) </script>
v-for 블록 내부에서는 부모 범위 속성에 대한 전체 액세스 권한이 있습니다. v-for는 현재 항목의 인덱스에 대해 선택적 두 번째 인수를 지원합니다.
<ul id="ex2"> <li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul> <script> var example2 = new Vue({ el: '#ex2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } }) </script>
in 대신에 of 구분자를 사용하여 iterators에 대한 JavaScript 구문에 더 가깝습니다.
<div v-for="item of items"></div>
객체와 v-for
v-for를 사용하여 객체의 속성을 반복할 수도 있습니다.
<ul id="ex3"> <li v-for="value in object"> {{ value }} </li> </ul> <script> var ex3 = new Vue({ el: "#ex3", data: { object: { title: "Hello Vue", author: "AGAL", data: "2020-08-13" } } }) </script>
속성 이름(예: 키)에 대한 두 번째 인수를 제공할 수도 있습니다.
<li v-for="(value, name) in object"> {{ name }} : {{ value }} </li>
인덱스에 대한 또 다른 예 :
<li v-for="(value, name, index) in object"> {{index}}. {{ name }} : {{ value }} </li>
객체를 반복할 때 순서는 Object.keys()의 열거 순서에 기반합니다. 이 순서는 JavaScript 엔진 구현 간에 일관성이 보장되지 않습니다.
상태 유지
Vue는 v-for로 렌더링된 요소 목록을 업데이트할 때 기본적으로 "in-place patch" 전략을 사용합니다. 데이터 항목의 순서가 변경된 경우 항목 순서와 일치하도록 DOM 요소를 이동하는 대신 Vue는 각 요소를 제자리에 패치하고 특정 인덱스에서 렌더링해야 하는 항목을 반영하는지 확인합니다. 이는 Vue 1.x에서 track-by="$index"의 동작과 유사합니다.
이 기본 모드는 효율적이지만 목록 렌더링 출력이 하위 구성 요소 상태 또는 임시 DOM 상태(예: 양식 입력 값)에 의존하지 않는 경우에만 적합합니다.
Vue가 각 노드의 ID를 추적하여 기존 요소를 재사용하고 재정렬 할 수 있도록 힌트를 제공하려면, 각 항목에 대해 고유한 key 속성을 제공해야합니다 .
<div v-for="item in items" v-bind:key="item.id"> <!-- content --> </div>
반복된 DOM 콘텐츠가 단순하지 않거나 성능 향상을 위해 의도적으로 기본 동작에 의존하는 경우가 아니라면 가능하면 v-for에 key 속성을 제공하는 것이 좋습니다.
Vue가 노드를 식별하는 일반적인 메커니즘이기 때문에 key에는 v-for에 특별히 연결되지 않은 다른 용도가 있습니다. 이 용도는 가이드 뒷부분에서 확인할 수 있습니다.객체 및 배열과 같은 기본이 아닌 값을 v-for키로 사용하지 마십시오 . 대신 문자열 또는 숫자 값을 사용하십시오.
key 속성 의 자세한 사용법은 key API 문서 를 참조하십시오.
배열 변경 감지
Mutation 메서드
Vue는 관찰된 배열의 Mutation 메서드를 래핑하여 뷰 업데이트도 트리거합니다. 래핑된 메서드는 다음과 같습니다.
-
push()
-
pop()
-
shift()
-
unshift()
-
splice()
-
sort()
-
reverse()
콘솔을 열고 Mutation 메서드를 호출 하여 이전 예제의 items 배열로 재생할 수 있습니다 . 예 :
example1.items.push({ message: 'Baz' })
배열 교체
이름에서 알 수 있듯이 Mutation 메서드는 호출된 원래 배열을 변경합니다. 이에 비해 원래 배열을 변경하지 않고 항상 새 배열을 반환하는 변경되지 않는 메서드 (예: filter(), concat()및 slice())도 있습니다. 비 Mutation 메서드로 작업 할 때 이전 배열을 새 배열로 바꿀 수 있습니다.
example1.items = example1.items.filter(function (item) { return item.message.match(/Foo/) })
이렇게 하면 Vue가 기존 DOM을 버리고 전체 목록을 다시 렌더링할 것이라고 생각할 수 있습니다. 운 좋게도 그렇지 않습니다. Vue는 일부 smart heuristics를 구현하여 DOM 요소 재사용을 극대화하므로 배열을 중복 객체가 포함된 다른 배열로 교체하는 것이 매우 효율적인 작업입니다.
주의 사항
JavaScript의 제한으로 인해 Vue가 배열 및 객체로 감지 할 수 없는 변경 유형이 있습니다. 이러한 내용은 반응성 섹션에서 설명합니다.
필터링 / 정렬된 결과 표시
때때로 우리는 원래 데이터를 실제로 변경하거나 재설정하지 않고 배열의 필터링되거나 정렬된 배열을 표시하려고합니다. 이 경우 필터링되거나 정렬된 배열을 반환하는 computed 속성을 만들 수 있습니다.
<ul id="ex4"> <li v-for="n in evenNumbers"> {{ n }} </li> </ul> <script> var ex4 = new Vue({ el: "#ex4", data: { numbers: [1, 2, 3, 4, 5] }, computed: { evenNumbers: function(){ return this.numbers.filter(function(number){ return number % 2 === 0 }) } } }) </script>
computed 속성이 실행 가능하지 않은 상황 (예 : 중첩 v-for 루프 내부)에서는 메서드를 사용할 수 있습니다.
<div id="ex5"> <ul v-for="set in sets"> <li v-for="n in even(set)">{{ n }}</li> </ul> </div> <script> var ex5 = new Vue({ el: "#ex5", data: { sets: [ [1, 2, 3, 4, 5], [6, 7, 8, 9, 10] ] }, methods: { even: function (numbers) { return numbers.filter(function(number){ return number % 2 === 0 }) } } }) </script>
Range 와 v-for
v-for 정수를 취할 수도 있습니다. 이 경우 템플릿을 여러 번 반복합니다.
<div> <span v-for="n in 10">{{ n }} </span> </div> <!-- 결과: 1 2 3 4 5 6 7 8 9 10 -->
<template>에서 v-for
v-if <template>과 마찬가지로 <template>태그에서 v-for를 사용하여 여러 요소의 블록을 렌더링 할 수도 있습니다. 예를 들면 :
<ul> <template v-for="item in items"> <li>{{ item.msg }}</li> <li class="divider" role="presentation"></li> </template> </ul>
v-for 와 v-if 함께 사용
v-if와 v-for를 함께 사용하는 것은 권장되지 않습니다. 자세한 내용은 스타일 가이드를 참조하세요.
동일한 노드에 존재하는 v-for는 v-if 보다 높은 우선 순위를 가집니다. 즉, 루프의 각 반복에서 v-if가 별도로 실행됩니다. 다음과 같이 일부 항목에 대해서만 노드를 렌더링하려는 경우에 유용합니다 .
<li v-for="todo in todos" v-if="!todo.isComplete"> {{ todo }} </li>
위는 완료되지 않은 todo만 렌더링합니다.
대신 루프 실행을 조건부로 건너뛰는 경우 v-if를 wrapper 요소 (또는 <template>)에 배치 할 수 있습니다 . 예를 들면 :
<ul v-if="todos.length"> <li v-for="todo in todos"> {{ todo }} </li> </ul> <p v-else>No todos left!</p>
컴포넌트와 v-for
이 섹션에서는 컴포넌트에 대한 지식이 있다고 가정합니다 . 건너 뛰고 나중에 다시 오셔도됩니다.
일반 요소와 같이 사용자 지정 컴포넌트에서 v-for를 직접 사용할 수 있습니다.
<my-component v-for="item in items" :key="item.id"></my-component>
2.2.0+에서는 컴포넌트와 함께 v-for를 사용할 때 key가 필요합니다.
그러나 구성 요소에는 자체 범위가 분리되어 있으므로 구성 요소에 데이터가 자동으로 전달되지 않습니다. 반복된 데이터를 컴포넌트로 전달하려면 props도 사용해야합니다.
<my-component v-for="(item, index) in items" v-bind:item="item" v-bind:index="index" v-bind:key="item.id" ></my-component>
구성 요소에 item을 자동으로 주입하지 않는 이유는 컴포넌트가 v-for의 작동 방식과 밀접하게 연결되기 때문입니다. 데이터의 출처를 명시하면 다른 상황에서 컴포넌트가 재사용될 수 있습니다.
다음은 간단한 Todo List의 완전한 예입니다.
<div id="todo-list-example"> <form v-on:submit.prevent="addNewTodo"> <label for="new-todo">Add a todo</label> <input v-model="newTodoText" id="new-todo" placeholder="E.g. Feed the cat" > <button>Add</button> </form> <ul> <li is="todo-item" v-for="(todo, index) in todos" v-bind:key="todo.id" v-bind:title="todo.title" v-on:remove="todos.splice(index, 1)" ></li> </ul> </div>
is="to-do-item" 속성에 유의하십시오. 이는 DOM 템플릿에서 필요한데, 이는 <li> 요소만 <ul> 내에서 유효하기 때문입니다. 이것은 <todo-item>과 같은 작업을 하지만 잠재적인 브라우저 구문 분석 오류를 중심으로 작동합니다. 자세한 내용은 DOM 템플릿 구문 분석 주의사항을 참조하시기 바랍니다.
Vue.component('todo-item', { template: '\ <li>\ {{ title }}\ <button v-on:click="$emit(\'remove\')">Remove</button>\ </li>\ ', props: ['title'] }) new Vue({ el: '#todo-list-example', data: { newTodoText: '', todos: [ { id: 1, title: 'Do the dishes', }, { id: 2, title: 'Take out the trash', }, { id: 3, title: 'Mow the lawn' } ], nextTodoId: 4 }, methods: { addNewTodo: function () { this.todos.push({ id: this.nextTodoId++, title: this.newTodoText }) this.newTodoText = '' } } })
$emit()
이벤트 발생은 컴포넌트의 통신 방법 중 하위 컴포넌트에서 상위 컴포넌트로 통신하는 방식입니다.
<!-- 상위 컴포넌트의 템플릿 --> <div id="app"> <child-component v-on:이벤트 명="상위 컴포넌트의 실행할 메서드 명 또는 연산"></child-component> </div> <script> // 하위 컴포넌트의 내용 this.$emit('이벤트 명'); </script>
반응형'Front-end > Vue.js' 카테고리의 다른 글
[가이드] 폼 입력 바인딩 - 필수요소 | Vue (0) 2020.08.14 [가이드] 이벤트 핸들링 - 필수요소 | Vue (0) 2020.08.14 [가이드] 클래스와 스타일 바인딩 - 필수요소 | Vue (0) 2020.08.12 [가이드] Computed와 Watch - 필수요소 | Vue (0) 2020.08.12 [가이드] 템플릿 문법 - 필수요소 | Vue (0) 2020.08.11 -