一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
vue的那些内置的组件
组件的切换
有些时候我们在tab栏切换组件我们可以用v-if或者v-show来控制组件
实例
<template>
<div class="like">
<div>
<ul class="list">
<li v-for="item in list" :key="item.id" @click="changeTab(item)" :class="[current ==item.id?'active':'']">
{{ item.title }}
</li>
</ul>
</div>
<div>
<div v-if="current == '0'">组件一</div>
<div v-if="current == '1'">组件二</div>
<div v-if="current == '2'">组件三</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
setup() {
const current = ref<string>("0");
const list = [
{
title: "Tab一",
id: "0",
},
{
title: "Tab二",
id: "1",
},
{
title: "Tab三",
id: "2",
},
];
const changeTab = (item) => {
console.log(item);
current.value = item.id;
};
return {
list,
changeTab,
current,
};
},
});
</script>
页面
动态组件 component
-
Props:
is- string | ComponentDefinition | ComponentConstructorinline-template- boolean
-
用法:
渲染一个“元组件”为动态组件。依
is的值,来决定哪个组件被渲染。<!-- 动态组件由 vm 实例的 `componentId` property 控制 --> <component :is="componentId"></component> <!-- 也能够渲染注册过的组件或 prop 传入的组件 --> <component :is="$options.components.child"></component>
实例
<template>
<div style="user-select: none;width: var(--page-width)">
<span class="h1">音乐馆</span>
<Tabs :tab-list="tabList" @changeTab="changeTab" :tabName="goToName"/>
<component :is="currentTabComponent" @change="change" />
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
import Tabs from '@/components/Tabs.vue'
import Featured from '@/pages/MusicHall/components/featured.vue'
import Leaderboard from '@/pages/MusicHall/components/leaderboard.vue'
import PrivateContent from '@/pages/MusicHall/components/privateContent.vue'
import PlayList from '@/pages/MusicHall/components/playList.vue'
import Artist from '@/pages/MusicHall/components/artist.vue'
import NewSong from '@/pages/MusicHall/components/newSong.vue'
import '@lottiefiles/lottie-player'
export default defineComponent({
name: 'MusicHall',
components: {
Tabs,
Featured,
Leaderboard,
PrivateContent,
PlayList,
Artist,
NewSong
},
setup() {
const goToName = ref('Featured')
const tabList = [
{ title: '精选推荐', name: 'Featured' },
{ title: '歌单', name: 'PlayList' },
{ title: '独家放送', name: 'PrivateContent' },
{ title: '排行榜', name: 'Leaderboard' },
{ title: '歌手', name: 'Artist' },
{ title: '新歌速递', name: 'NewSong' }
]
const currentTabComponent = ref('Featured')
const changeTab = (tabName:string) => {
currentTabComponent.value = tabName
goToName.value = ''
}
const change = (tabName:string) => {
goToName.value = tabName
}
return {
tabList,
currentTabComponent,
goToName,
changeTab,
change
}
}
})
</script>
<style scoped>
</style>
页面效果
结合路由占位符来使用内置组件
<router-view> 的 v-slot#
<router-view> 暴露了一个 v-slot API,主要使用 <transition> 和 <keep-alive> 组件来包裹你的路由组件。
<router-view v-slot="{ Component }" >
<transition name="switch-route" mode="out-in">
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
实例
<template>
<div class="main">
<a-layout>
<a-layout-sider>
<div class="img"><img src="../../assets/image/logo.png" alt="" /></div>
<a-menu
mode="inline"
v-model:selectedKeys="selectedKeys"
@click="pageChange"
>
<a-menu-item :key="item.path" v-for="item in list">
<user-outlined />
<component :is="item.icon" style="margin-right: 5px" />
<span class="nav-text">{{ item.label }}</span>
</a-menu-item>
</a-menu>
</a-layout-sider>
<a-layout>
<a-layout-header>Header</a-layout-header>
<a-layout-content class="content">
<div>
<router-view v-slot="{ Component }" class="view">
<transition name="switch-route" mode="out-in">
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
</div>
</a-layout-content>
<a-layout-footer>Footer</a-layout-footer>
</a-layout>
</a-layout>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
interface item {
index: number;
label: string;
icon: string;
path: string;
}
export default defineComponent({
setup() {
const router = useRouter();
const selectedKeys = ref<string[]>(["0"]);
const list = [
{
index: 0,
label: "我喜欢",
icon: "myLike",
path: "/myLike",
},
{
index: 1,
label: "音乐",
icon: "music",
path: "/music",
},
];
const pageChange = (e) => {
console.log(e);
router.push({ path: e.key });
};
return {
selectedKeys,
list,
pageChange,
};
},
});
</script>
<style lang="less" scoped>
.main {
height: 1000px;
.img {
background-color: #fff;
}
.ant-layout,
.ant-layout-has-sider {
height: 100%;
}
.ant-layout-sider {
background-color: #fff;
}
.ant-layout-header {
background-color: #fff;
height: 100px;
}
}
.mian .content {
background: #fafafa;
overflow: hidden;
position: relative;
}
.switch-route-leave-active,
.switch-route-enter-active {
transition: all .5s;
}
.switch-route-enter {
opacity: 0;
transform: translateX(-30px);
}
</style>