vue的那些内置的组件 component

415 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

vue的那些内置的组件

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>

页面

捕获1111.PNG

动态组件 component

  • Props

    • is - string | ComponentDefinition | ComponentConstructor
    • inline-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>

页面效果

捕获231.PNG

结合路由占位符来使用内置组件

<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>