<section id="app">
<ul>
<li>
<h2>Manuel Lorenz</h2>
<button>Show Details</button>
<ul>
<li><strong>Phone:</strong> 01234 5678 991</li>
<li><strong>Email:</strong>manuel@localhost.com</li>
</ul>
</li>
<li>
<h2>Julie Jones</h2>
<button>Show Details</button>
<ul>
<li><strong>Phone:</strong> 09876 543 221</li>
<li><strong>Email:</strong>julie@localhost.com</li>
</ul>
</li>
</ul>
</section>
위 예제에 Manuel, Julie 두 친구의 list 항목이 들어있는 ul이 있다.
현재는 Vue앱이 없다. 이를 하나의 Vue 앱으로 관리할 수 있다.
친구 데이터를 HTML 코드에 하드코딩하는 대신, Vue 코드로 Vue 애플리케이션에 보관해보자.
즉, 위 코드처럼 li 항목들을 HTML 코드로 하드코딩하지않고, Vue.js를 사용해 동적으로 렌더링해보자.
Vue앱의 data 프로퍼티에 friends로 저장해보자.
app.js
const app = Vue.createApp({
data() {
return {
friends: [
{
id: "manuel",
name: "Manuel Lorenz",
phone: "01234 5678 991",
email: "manuel@localhost.com",
},
{
id: "julie",
name: "Julie Jones",
phone: "09876 543 221",
email: "julie@localhost.com",
},
],
};
},
methods: {},
});
index.html
<section id="app">
<ul>
<li v-for="friend in friends" :key="friend.id">
<h2>{{ friend.name }}</h2>
<button>Show Details</button>
<ul>
<li><strong>Phone:</strong> {{ friend.phone }}</li>
<li><strong>Email:</strong> {{ friend.email }}</li>
</ul>
</li>
</ul>
</section>
이제 데이터는 JS로 관리한다.
실제 data는 데이터베이스에서 가져올 수도 있고, 사용자가 입력한 것일 수도 있다.
v-for를 이용하면 v-for 이용 전과 화면은 같지만, Vue를 활용하면서 HTML 코드가 줄었다.
하지만 'Show Details'버튼은 작동하지 않는다. ← 이 부분이 까다롭다.
toggleDetails 메서드를 추가하고 호출하여 버튼에 연결하고, 버튼을 클릭해서 details를 숨기고 표시할 수 있다.
detailsAreVisible이라는 data 프로퍼티를 추가하고, 초기값은 false로 설정해 처음에는 세부정보를 표시하지 않는다.
const app = Vue.createApp({
data() {
return {
friends: [
{
id: "manuel",
name: "Manuel Lorenz",
phone: "01234 5678 991",
email: "manuel@localhost.com",
},
{
id: "julie",
name: "Julie Jones",
phone: "09876 543 221",
email: "julie@localhost.com",
},
],
detailsAreVisible: false,
};
},
methods: {
toggleDetails(){
this.detailsAreVisible = !this.detailsAreVisible;
},
},
});
그리고 button 클릭 시, toggleDetails가 트리거 되도록 이벤트바인딩을 한다.
세부정보가 들어있는 ul 태그에는 v-if값을 설정해 DOM에 추가여부를 제어한다.
버튼의 라벨도 동적으로 변경가능하다. (computed 프로퍼티로 사용 가능.)
index.html
<ul>
<li v-for="friend in friends" :key="friend.id">
<h2>{{ friend.name }}</h2>
<button @click="toggleDetails">
{{ detailsAreVisible ? 'Hide' : 'Show' }}Details <!--버튼 라벨 동적으로-->
</button>
<ul v-if="detailsAreVisible"> <!--v-if값을 설정해 DOM에 추가여부를 제어-->
<li><strong>Phone:</strong> {{ friend.phone }}</li>
<li><strong>Email:</strong> {{ friend.email }}</li>
</ul>
</li>
</ul>
새로고침 시, 아래와 같이 버튼이 표시된다.
# 문제점
문제는, 어떤 친구 항목에서 버튼을 누르는지와는 관계 없이, 어떤 버튼을 누르든 일괄적으로 세부정보가 같이 사라지고 같이 보여진다.
그 이유는 분명하다.
v-for에서 여러 개의 li항목을 출력했다. 하지만 모든 li항목의 button은 항상 같은 method인 toggleDetails를 가리키고 있다.
즉, 어떤 친구의 button을 누르든지 항상 같은 메서드를 호출하고,
또한 두 친구의 세부정보 표시제어를 같은 detailsAreVisible로 하고있기 때문.
# 해결책 ?
해결책을 생각해보자.
toggleDetails 메서드에 id값을 전달해보자.
<ul>
<li v-for="friend in friends" :key="friend.id">
<h2>{{ friend.name }}</h2>
<button @click="toggleDetails(friend.id)">
{{ detailsAreVisible ? 'Hide' : 'Show' }}Details
</button>
<ul v-if="detailsAreVisible">
<li><strong>Phone:</strong> {{ friend.phone }}</li>
<li><strong>Email:</strong> {{ friend.email }}</li>
</ul>
</li>
</ul>
그런 다음, app.js파일에서 toggleDetails메서드에 id를 전달하여
data에 detailsAreVisibleA, detailsAreVisibleB 두 개의 프로퍼티로 나눠서 작동하게 설정할 수 있다.
But, 많이 번거롭다. 이렇게 하는건 궁극적인 방법이 아니다.
만약 유저가 새 친구를 추가할 수 있게 한다면, data의 friends 프로퍼티의 리스트는 동적으로 증가하므로 detailsAreVisibleA, B, C 이렇게 하는 것도 좋지 않다. 프로퍼티의 개수를 예상하는 것도 불가능하다.
# 컴포넌트
대신, 이 문제는 컴포넌트를 활용하면 쉽게 해결할 수 있다!
** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.
'Vue.js' 카테고리의 다른 글
[Udemy Vue 완벽가이드 Section6] 72. 복잡한 사용자 인터페이스 구축에 컴포넌트를 사용하는 이유 (0) | 2023.08.17 |
---|---|
[Udemy Vue 완벽가이드 Section6] 71. 컴포넌트 소개 (0) | 2023.08.17 |
[Udemy Vue 완벽가이드 Section5] 66. Vue 앱 생명주기 - 이론, 실습 (0) | 2023.08.16 |
[Udemy Vue 완벽가이드 Section5] 64. Ref 활용하기 (0) | 2023.08.15 |
[Udemy Vue 완벽가이드 Section5] 63. 템플릿 이해하기 (0) | 2023.08.15 |