Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus
一、动态组件
通过内置组件 的 is 属性,动态指定需要显示的组件。
动态组件实现 Tab 切换的效果:
演示代码:
<script setup> import Tab1 from '../components/tabs/Tab1.vue'; import Tab2 from '../components/tabs/Tab2.vue'; import Tab3 from '../components/tabs/Tab3.vue'; import { ref, shallowRef, markRaw, reactive } from "vue" // let cutComp = ref(Tab1) let cutComp = shallowRef(Tab1) let cutIdx = ref(0) let data = reactive([{ id: 1, title: "国际新闻", tabName: markRaw(Tab1) }, { id: 2, title: "国内新闻", tabName: markRaw(Tab2) }, { id: 3, title: "热点新闻", tabName: markRaw(Tab3) }]) const toggleTab = (idx) => { cutIdx.value = idx cutComp.value = data[idx].tabName } </script> <template> <div class="tab-wrap"> <!-- Vue中提供了component元组件用于实现组件的动态切换,基于特殊的属性 is;可以用于切换自定义组件,也可以用于切换原生DOM,当然内置组件也是可以的 --> <!-- <component :is="Tab1"></component> <component is="input"></component> --> <!-- 选项卡切换 --> <!-- <ul> <li>国际新闻</li> <li>国内新闻</li> <li>热点新闻</li> </ul> --> <ul> <li v-for="item, index in data" :class="index == cutIdx ? 'active' : ''" @click="toggleTab(index)">{{ item.title }}</li> </ul> <div class="content"> <component :is="cutComp"></component> </div> </div> </template> <style lang="scss" scoped> .tab-wrap { width: 300px; ul { list-style: none; display: flex; padding: 0; justify-content: space-between; border: 1px solid #e3e3e3e3; } li { flex: 1; padding: 6px 0; text-align: center; cursor: pointer; &.active { color: blue; font-weight: bold; } } } .content { height: 160px; padding: 10px; border: 1px solid #e7e7e7; } </style>
二、递归组件
递归组件类似于递归函数,就是在当前组件内调用组件本身。一般情况下,不需要 import 引入直接使用即可。
2.1 递归组件演示
<script> export default { name: "MyRecursion" } </script> <script setup> const props = defineProps({ obj: { type: Array, default: () => [] } }) const showItem = (title) => { console.log(title) } </script> <template> <div> <ul v-for="item in obj"> <li @click="showItem(item.title)"><strong>{{ item.title }}</strong></li> <!-- <Tab1 v-if="item?.children?.length" :obj="item?.children" /> --> <MyRecursion v-if="item?.children?.length" :obj="item?.children" /> </ul> </div> </template>
2.2 定义组件别名
- 采用选项式API语法多写一个 script 去通过 name 注册一个组件别名,当前组件内调用这个组件别名。
<script> export default { name:"OtherComponentName" } </script> <script setup> /* 当前组件式 API 相关代码 */ </script> <template> /* 模板代码 */ </template> <style lang='scss' scoped> /* 样式代码 */ </style>
unplugin-vue-define-options
插件定义组件别名
Element Plus 源码使用这个插件来对组件名进行注册,所以我们完全可以放心的使用。
- 1. 安装插件
npm install unplugin-vue-define-options -D
2. vite.config.js
文件添加插件
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import DefineOptions from 'unplugin-vue-define-options/vite'; // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue(), DefineOptions()], });
- 3. 配置完成后,就可以在组件中直接使用了
<template> <button> </button> </template> <script setup> defineOptions({ name: 'TButton', }); </script> <style scoped></style>