A06-批量注册组件
🧑🎓 个人主页:Silence Lamb
📖 本章内容:【批量注册组件】
Silence-Vue v1.0.0
基于VUE前端快速开发框架
一、批量注册组件
1.1【批量注册组件】
- 🍁批量注册组件:src/components/index.js
/* 方法从指定目录(@/components)和其子目录中加载所有 Vue.js 组件(因为第二个参数设置为 true)* require.context 方法来创建一个文件上下文* 第三个参数 (/\\.vue$/) 指定我们只想加载具有 .vue 扩展名的文件*/
const componentFiles = require.context('@/components', true, /\\.vue$/)
/* 注册组件* @param app*/
export default (app) => {/*遍历componentFiles的组件*/componentFiles.keys().forEach(e => {/*.keys() 方法迭代每个文件,并使用 .default 获取从每个文件导出的默认组件*/const component = componentFiles(e).defaultapp.component(component.name, component)})
}
- 🍁全局引入:src/main.js
import components from '@/components/index' // components
const app = createApp(App)
//全局批量注册组件
components(app)
1.2【回到顶部组件】
- 🍁回到顶部组件:src/components/scrollToTop/index.vue
<template><div class="components-container"><button @click="scrollToTop" v-if="showScrollTopBtn" class="scroll-top"><svg-icon icon-class="guide"/></button></div>
</template><script>
export default {name: 'scrollToTop',data() {return {showScrollTopBtn: false}},methods: {scrollToTop() {let scrollTopDuration = 500;let scrollStep = -window.scrollY / (scrollTopDuration / 15);let scrollInterval = setInterval(function () {if (window.scrollY != 0) {window.scrollBy(0, scrollStep);} else clearInterval(scrollInterval);}, 15);}},mounted() {let vm = this;window.addEventListener("scroll", function () {if (window.pageYOffset > 100) {vm.showScrollTopBtn = true;} else {vm.showScrollTopBtn = false;}});}
}
</script><style lang= "scss" scoped>
.scroll-top {position: fixed;bottom: 80px;right: 10px;background-color: #799ba12e;color: #ffffff;border: none;padding: 16px;border-radius: 50%;z-index: 9999;animation: swing 2s ease-in-out 1s infinite;transform-origin: bottom center;display: flex;
}@keyframes swing {0% {transform: rotate(0);}10% {transform: rotate(15deg);}20% {transform: rotate(-10deg);}30% {transform: rotate(10deg);}40% {transform: rotate(-5deg);}50% {transform: rotate(5deg);}60% {transform: rotate(-5deg);}70% {transform: rotate(0);}90% {transform: rotate(0);}100% {transform: rotate(0);}
}.scroll-top:hover {background-color: #7fa19b;animation: none;
}
</style>
1.2【页面使用组件】
- 🍁页面使用组件:src/views/index.vue
<template><div :class="classObj" class="app-wrapper"><!-- 回到顶部小组件--><scrollToTop/></div>
</template>
🌟其他页面就无需引入组件
import scrollToTop from './components/scrollToTop/index'
components: {scrollToTop }
二、批量安装插件
- 🌍 自定义插件:src\\utils\\tools\\token\\index.js
export default {/* 判断是否为外部图标* @param {string} path* @returns {Boolean}*/isExternal(path) {return /^(https?:|mailto:|tel:)/.test(path)},
}
- 🌍 安装插件:src\\utils\\plugins\\index.js
const methods = require.context('./modules/', true, /\\.js$/)/* 安装插件*/
export default {install(app) {// 加载在某个目录中动态注册的所有全局方法methods.keys().forEach((filePath) => {const method = methods(filePath).defaultconst fileName = getFileName(filePath)// 将该方法注册为 $fileName 的全局方法Object.keys(method).forEach((key) => {app.config.globalProperties['$' + fileName] = method})})},
}
/* 获取最后一个文件夹* @param {string} filePath* @returns 子文件夹名*/
function getFileName(filePath) {const matches = filePath.substring(0, filePath.lastIndexOf('/')).split('/').pop()return matches
}
- 🌍 全局引入:src\\main.js
import { createApp } from 'vue'
import App from './App.vue'
import plugins from '@/utils/plugins/index.js' // plugins
const app = createApp(App)
app.use(plugins)
app.mount('#app')
- 🌍 组件使用注册的方法:src\\views\\index\\index.vue
methods: {getMessage(event) {console.log(this.$validate.isExternal('http://localhost/index'))},},
三、批量引入方法
- 🌍 方法定义格式:src\\utils\\tools\\token\\index.js
import Cookies from 'js-cookie'const TokenKey = 'Admin-Token'/* 获取Token* @returns token*/
export function getToken() {return Cookies.get(TokenKey)
}/* 设置Token* @param {*} token*/
export function setToken(token) {return Cookies.set(TokenKey, token)
}/* 移除Token*/
export function removeToken() {return Cookies.remove(TokenKey)
}
- 🌍 全局引入:src\\utils\\tools\\token\\index.js
const tools = require.context('./tools/', true, /\\.js$/)/* 动态引入方法*/
export default {install(app) {console.log(tools)var methods=tools.concat(plugins)// 加载在某个目录中动态注册的所有全局方法methods.keys().forEach((filePath) => {const method = methods(filePath)const fileName = getLastFileName(filePath)// 将该方法注册为 $fileName 的全局方法app.config.globalProperties['$' + fileName] = method})},
}
/* 获取最后一个文件夹* @param {string} filePath* @returns 子文件夹名*/
function getLastFileName(filePath) {const matches = filePath.substring(0, filePath.lastIndexOf('/')).split('/').pop()return matches
}
- 🌍 全局引入:src\\main.js
import { createApp } from 'vue'
import App from './App.vue'
import utils from '@/utils/index' // utils
const app = createApp(App)
app.use(utils)
app.mount('#app')
- 🌍 组件中使用:src\\main.js
methods: {getMessage(event) {console.log(this.$getToken())},}
四、组件按需导入
- 🍁组件按需导入:vue.config.js
npm install -D unplugin-vue-components
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')configureWebpack: { plugins: [/* 组件按需自动导入*/Components({//引入自己的组件dirs: ['src/components'],//引入ElementPlus官方组件resolvers: [ElementPlusResolver()],dts: 'src/auto/components.d.ts',// 自定义规则libs: [{libraryName: 'element-plus',esModule: true,resolveStyle: (name) => {return `element-plus/lib/theme-chalk/${name}.scss`},},],}),]}
- 🌍会自动生成:src\\auto\\components.d.ts
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'export {}declare module '@vue/runtime-core' {export interface GlobalComponents {....RouterLink: typeof import('vue-router')['RouterLink']RouterView: typeof import('vue-router')['RouterView']}
}
五、依赖自动导入
- 🌍可自动导入使用到的vue、vue-router等依赖
- 🍁依赖自动导入:vue.config.js
npm install -D unplugin-auto-import
import AutoImport from 'unplugin-auto-import/vite'export default defineConfig({// ...plugins: [/* 依赖自动按需导入*/AutoImport({//解决ElemenPlus消息提示框导入问题resolvers: [ElementPlusResolver()],imports: ['vue', 'vue-router', 'vuex', '@vueuse/head'],// 可以选择auto-import.d.ts生成的位置,使用ts建议设置为'src/auto-import.d.ts'dts: 'src/auto/auto-import.d.ts',}),]
})
- 🌍会自动生成:src\\auto\\auto-import.d.ts
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-auto-import
export {}
declare global {const EffectScope: typeof import('vue')['EffectScope']const ElLoading: typeof import('element-plus/es')['ElLoading']const ElMessage: typeof import('element-plus/es')['ElMessage']const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']const ElNotification: typeof import('element-plus/es')['ElNotification']const computed: typeof import('vue')['computed']const createApp: typeof import('vue')['createApp']const createLogger: typeof import('vuex')['createLogger']const createNamespacedHelpers: typeof import('vuex')['createNamespacedHelpers']const createStore: typeof import('vuex')['createStore']const customRef: typeof import('vue')['customRef']const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']const defineComponent: typeof import('vue')['defineComponent']const effectScope: typeof import('vue')['effectScope']const getCurrentInstance: typeof import('vue')['getCurrentInstance']const getCurrentScope: typeof import('vue')['getCurrentScope']const h: typeof import('vue')['h']const inject: typeof import('vue')['inject']const isProxy: typeof import('vue')['isProxy']const isReactive: typeof import('vue')['isReactive']const isReadonly: typeof import('vue')['isReadonly']const isRef: typeof import('vue')['isRef']const mapActions: typeof import('vuex')['mapActions']const mapGetters: typeof import('vuex')['mapGetters']const mapMutations: typeof import('vuex')['mapMutations']const mapState: typeof import('vuex')['mapState']const markRaw: typeof import('vue')['markRaw']const nextTick: typeof import('vue')['nextTick']const onActivated: typeof import('vue')['onActivated']const onBeforeMount: typeof import('vue')['onBeforeMount']const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']const onDeactivated: typeof import('vue')['onDeactivated']const onErrorCaptured: typeof import('vue')['onErrorCaptured']const onMounted: typeof import('vue')['onMounted']const onRenderTracked: typeof import('vue')['onRenderTracked']const onRenderTriggered: typeof import('vue')['onRenderTriggered']const onScopeDispose: typeof import('vue')['onScopeDispose']const onServerPrefetch: typeof import('vue')['onServerPrefetch']const onUnmounted: typeof import('vue')['onUnmounted']const onUpdated: typeof import('vue')['onUpdated']const provide: typeof import('vue')['provide']const reactive: typeof import('vue')['reactive']const readonly: typeof import('vue')['readonly']const ref: typeof import('vue')['ref']const resolveComponent: typeof import('vue')['resolveComponent']const shallowReactive: typeof import('vue')['shallowReactive']const shallowReadonly: typeof import('vue')['shallowReadonly']const shallowRef: typeof import('vue')['shallowRef']const toRaw: typeof import('vue')['toRaw']const toRef: typeof import('vue')['toRef']const toRefs: typeof import('vue')['toRefs']const triggerRef: typeof import('vue')['triggerRef']const unref: typeof import('vue')['unref']const useAttrs: typeof import('vue')['useAttrs']const useCssModule: typeof import('vue')['useCssModule']const useCssVars: typeof import('vue')['useCssVars']const useHead: typeof import('@vueuse/head')['useHead']const useLink: typeof import('vue-router')['useLink']const useRoute: typeof import('vue-router')['useRoute']const useRouter: typeof import('vue-router')['useRouter']const useSlots: typeof import('vue')['useSlots']const useStore: typeof import('vuex')['useStore']const watch: typeof import('vue')['watch']const watchEffect: typeof import('vue')['watchEffect']const watchPostEffect: typeof import('vue')['watchPostEffect']const watchSyncEffect: typeof import('vue')['watchSyncEffect']
}
// for type re-export
declare global {// @ts-ignoreexport type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'
}