个人主页:Silence Lamb
本章内容:【批量注册组件】
/**
* 方法从指定目录(@/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).default
app.component(component.name, component)
})
}
import components from '@/components/index' // components
const app = createApp(App)
//全局批量注册组件
components(app)
<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>
<template>
<div :class="classObj" class="app-wrapper">
<scrollToTop/>
div>
template>
其他页面就无需引入组件
import scrollToTop from './components/scrollToTop/index'
components: {scrollToTop }
export default {
/**
* 判断是否为外部图标
* @param {string} path
* @returns {Boolean}
*/
isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
},
}
const methods = require.context('./modules/', true, /\.js$/)
/**
* 安装插件
*/
export default {
install(app) {
// 加载在某个目录中动态注册的所有全局方法
methods.keys().forEach((filePath) => {
const method = methods(filePath).default
const 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
}
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')
methods: {
getMessage(event) {
console.log(this.$validate.isExternal('http://localhost/index'))
},
},
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)
}
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
}
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')
methods: {
getMessage(event) {
console.log(this.$getToken())
},
}
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`
},
},
],
}),
]
}
/* 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']
}
}
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',
}),
]
})
/* 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-ignore
export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'
}