탭으로 페이지를 이동할때 동적으로 컴포넌트를 변경할 경우가 있다.
예를들어 url은 고정시키고 보여주는 화면만 변경하고 싶을때..
// 탭 이용하는 페이지
<template>
<div style="margin-bottom: 300px">
<ui-tab
:tabs="tabs"
v-model="selectedTab"
propType="underline-dark"
class="us-mt--10"
@change="handleChangeTab"
/>
<!-- 동적 컴포넌트 연결 -->
<component :is="currentTabComponent" />
</div>
</template>
<script>
export default {
name: "credit-info-index",
layout: "credit",
created() {
this.$parent.$emit("setTitle", "내 신용 정보");
},
data() {
return {
tabs: [
{ id: 0, title: "카드", name: "card" },
{ id: 1, title: "대출", name: "loan" },
{ id: 2, title: "연체", name: "overdue" },
{ id: 3, title: "보증", name: "surety" },
],
selectedTab: 0,
// 함수 형식으로 import 해온 컴포넌트를 data에 담아둔다.
currentTabComponent: () => import("./card.vue"),
};
},
computed: {
tab() {
return this.$route.query.tab;
},
},
methods: {
handleChangeTab(selectedTab) {
// 동적 컴포넌트 변경
this.currentTabComponent = () =>
import(`./${this.tabs[selectedTab].name}.vue`);
this.$router.replace({
path: "/credit/info",
query: { tab: this.tabs[selectedTab].name },
});
},
},
mounted() {
// console.log(this.tab);
if (this.tab) {
this.selectedTab = this.tabs.find((t) => t.name === this.tab).id;
this.currentTabComponent = () => import(`./${this.tab}.vue`);
}
},
};
</script>
// 탭 컴포넌트
<template>
<div class="hb-tab" :class="{'hb-tab--dark': mode === 'dark'}">
<div
v-for="(tab,index) in tabs"
:key="index"
:data-cy="`tab-${tab.id}`"
class="hb-tab__each-wrapper"
>
<input
type="radio"
name="tab-group"
:id="`hb-tab-${tab.id}`"
@click="handleClickTab(tab.id)"
:checked="selectedTab === tab.id"
:disabled="tab.disabled"
/>
<label
:for="`hb-tab-${tab.id}`"
class="hb-tab__each"
:class="`hb-tab__each--${propType} `"
>
{{tab.title}}
</label>
</div>
</div>
</template>
<script>
export default {
name: "hb-tab",
// radio 버튼을 이용하기 때문에 v-model을 model 옵션을 이용해 표현해줘야 한다.
model: {
// 부모 컴포넌트에서 전달받은 selectedTab prop
prop: "selectedTab",
event: "change" // @change에서 쓰일 것으므로
},
props: {
selectedTab: {
type: [Number, String]
},
tabs: {
type: Array,
default: function() {
return [];
}
},
mode: {
type: String,
require: false
},
propType: {
type: String,
default: ""
},
},
data() {
return {};
},
methods: {
handleClickTab(val) {
this.$emit("change", val);
}
}
};
</script>
- import 해온 컴포넌트를 data에 담아두는 것
- v-model을 prop 형태로 이용하기 위해서는 model 옵션을 사용하는 것
두가지에 핵심이 있다.