vue로 구현하는 예제(ver.7)입니다.
- 리팩토링, 공통 컴포넌트화 -
예제는 인프런의 캡틴 판교, "장기효"님의 Vue.js 완벽 가이드 - 실습과 리팩토링으로 배우는 실전 개념을
들으면서 공부한 내용입니다.
리팩토링 컴포넌트 공통화
페이지에서 사용되는 컴포넌트들의 패턴이 중복되어 사용되었을 때
이를 공통 컴포넌트화 시킴으로써 코드를 간편화, 구조화시킵니다.
구현 내용
각각의 페이지에서 사용되는 user information을 하나의 컴포넌트화 시키기 위한 작업을 합니다.
리팩터링 작업
· components > UserProfile.vue 파일 생성
· 기존의 ItemView.vue의 내용(위 오른쪽 UI)을 copy
<template>
//기존 ItemView.vue 내용 일단 copy
<div class="user-container">
<div>
<i class="fas fa-user"></i>
</div>
<div class="user-desc">
//아래 부분 fetchedItem -> 사용자 정보 데이터로 바꿔줘야함(방법 2가지)
<router-link :to="`/user/${fetchedItem.user}`">
{{ fetchedItem.user }}
</router-link>
<div class="time">
{{ fetchedItem.time_ago }}
</div>
</div>
</div>
</template>
Before
views > UserView.vue
<template>
<div>
<div>name : {{ userInfo.id }}</div>
<div>karma : {{ userInfo.karma }}</div>
<div>created : {{ userInfo.created }}</div>
</div>
</template>
after
· UserView.vue에 UserProfile.vue import
<template>
<div>
<user-profile></user-profile>
</div>
</template>
<script>
import UserProfile from "../components/UserProfile.vue";
export default {
components: { UserProfile },
//computed 속성 공식문서에 의해 life cycle 위에 위치
computed: {
userInfo() {
return this.$store.state.user;
},
},
created() {
const userName = this.$route.params.id;
this.$store.dispatch("FETCH_USER", userName);
},
};
</script>
UserProfile에서 fetchedItem 부분에 user 정보 가지고 오는 방법 2가지
· computed에서 전달: UserView의 computed의 userInfo 객체를 그대로 가져와서 출력
· props로 전달: UserView에서 userInfo부분을 props로 전달
공통 컴포넌트화: 하위 컴포넌트에 computed로 데이터 전달
components > UserProfile.vue
<template>
<div class="user-container">
<div>
<i class="fas fa-user"></i>
</div>
<div class="user-desc">
<div>{{ userInfo.id }}</div> //2. userInfo로 변경
<div class="time">
{{ userInfo.created }} //2. userInfo로 변경
</div>
</div>
</div>
</template>
<script>
export default {
computed: { //1. UserView의 computed의 userInfo 그대로 가져옴
userInfo() {
return this.$store.state.user;
},
},
};
</script>
공통 컴포넌트화: 하위 컴포넌트에 props로 데이터 전달
userView.vue(상위 컴포넌트)
<template>
<div>
<user-profile :info="userInfo"></user-profile> //computed의 userInfo 속성을 props로 전달
</div>
</template>
userProfile.vue(하위 컴포넌트)
<template>
<div class="user-container">
<div>
<i class="fas fa-user"></i>
</div>
<div class="user-desc">
<div>{{ info.id }}</div> //2. info로 변경
<div class="time">
{{ info.created }} //2. info로 변경
</div>
</div>
</div>
</template>
<script>
export default {
props: { //1. info를 props로 전달받음
info: Object,
},
};
결론
vuex의 구조에 흐름에 맞는 방법은,
computed에 바로 접근하여 state로부터 데이터를 바로 가지고 오는 것이
더 적절합니다.
slot
하위 컴포넌트에서 slot을 이용하여 미완성의 틀만 만들고,
상위 컴포넌트에서 정의를 합니다.
UserProfile.vue(하위 컴포넌트)
<template>
<div class="user-container">
<div>
<i class="fas fa-user"></i>
</div>
<div class="user-desc">
<slot name="username"></slot> //slot 정의
<div class="time">
<slot name="time"></slot> //slot 정의
<slot name="karma"></slot> //slot 정의
</div>
</div>
</div>
</template>
UserView.vue(상위 컴포넌트)
<template>
<div>
<user-profile :info="userInfo">
<div slot="username">{{ userInfo.id }}</div> //slot="slot 이름" 으로 호출
<span slot="time">{{ "Joined " + userInfo.created }}, </span> //slot 호출
<span slot="karma">{{ userInfo.karma }}</span> //slot 호출
</user-profile>
</div>
</template>
'개발 > React' 카테고리의 다른 글
[react] 리액트로 구구단 게임 만들기(ft. hooks 방식, cdn 설치) (0) | 2021.03.14 |
---|---|
[vue] vue.js props / emit 사용방법 (0) | 2021.02.03 |
[vue] vue 리팩토링: 공통 컴포넌트화(api 통해 뉴스 사이트 구현 ver.6) (0) | 2021.01.23 |
[vue] vue getters, v-html, transition(api 통해 뉴스 사이트 구현 ver.5) (0) | 2021.01.21 |
[vue] vue.js vue 동적 라우트(api 통해 뉴스 사이트 구현 ver.4) (0) | 2021.01.18 |
댓글