vue3+vite 实现自动导入路由+组件

2023年1月19日11:26:32

router.js文件

import {createRouter, createWebHistory} from 'vue-router'

let _Vue
export default function install(Vue) {
    if (install.installed && _Vue === Vue) return
    install.installed = true
    _Vue = Vue

    //杠+后面的字母变为大写字母并去除杠
    function toCamelCase(str) {
        if (!str) return '';
        return str.replace(/-(\w)/g, function ($0, $1) {
            return $1.toUpperCase()
        })
    }

    //首字母大写
    function capitalizeFirstLetter(str) {
        return str.charAt(0).toUpperCase() + str.slice(1)
    }

    const routerList = [], childrenList = [];
   	// vite导入文件方法
    const requireComponent = import.meta.globEager('./views/**/*.vue');
    //使用文件内name值列表
    const useDefaultNameList = {};
    //不全局导入列表
    const doNotRegisterList = {
        'Home': !0
    };

    //自动注册
    const myModules = {};
    for (let i in requireComponent) {
    	if(!requireComponent.hasOwnProperty(i)) continue;
        const componentConfig = requireComponent[i];
        let camelCaseName, firstLetter,
            componentName = capitalizeFirstLetter(toCamelCase(i.replace('./views/', '')
                .replace(/\//g, '-').replace('.vue', '')));
        if (useDefaultNameList[componentName]) {
            camelCaseName = toCamelCase(componentConfig.default.name);
            componentName = firstLetter = capitalizeFirstLetter(camelCaseName);
        }
        if (myModules[componentName]) continue;
        if (!doNotRegisterList[componentName]) {
            const {params = '', parentName = '', pathIsNullCharacter = false} = componentConfig.default._pageParams || {};
            const component = {
                name: componentName,
                path: !pathIsNullCharacter ? ((parentName ? '' : '/') + componentName + params) : '',
                component: componentConfig.default || componentConfig,
                children: []
            };
            if (parentName) {
                delete component.children;
                const child = childrenList.find(item => item.name === parentName);
                if (child) {
                    child.children.push(component);
                } else {
                    childrenList.push({
                        name: parentName,
                        children: [component]
                    })
                }
            } else {
                routerList.push(component)
            }
            myModules[componentName] = !0;
        }
    }
    for (let i = 0; i < routerList.length; i++) {
        let parent = routerList[i];
        let index = childrenList.findIndex(item => item.name === parent.name);
        if (index > -1) {
            let child = childrenList[index];
            childrenList.splice(index, 1);
            parent.children = child.children;
        }
    }
    const routes = [
        {
            path: '/',
            name: 'Home',
            component: () => import("./views/home.vue")
        },
        ...routerList
    ];
    const router = createRouter({
        history: createWebHistory(),
        // history: createWebHashHistory(),
        routes
    })
    Vue.use(router)
}

vue页面

   <template>
  <div class="eventIndex">
    <div>asfkafjasfjafijiofj</div>
    <router-view :key="$route.path" />
    <button @click="jumpPage">继续跳啊</button>
  </div>
</template>

<script>
export default {
  name: "eventIndex",
  //自动导入时需要用到的参数
  _pageParams: {
  //路由需要用到的参数
    params: '/:id?/:menuId?',
    //path是否是''字符串
    pathIsNullCharacter: true,
    //父组件的名字,如果有这个参数,则是子组件
    parentName: ''
  },
  methods: {
    jumpPage(){
      this.$router.push('/EventDetail')
    }
  }
}
</script>

<style scoped>

</style>

下方为自动导入组件(components.js)

let _Vue
export default function install(Vue) {
    if (install.installed && _Vue === Vue) return
    install.installed = true
    _Vue = Vue

    //杠+后面的字母变为大写字母并去除杠
    function toCamelCase(str) {
        if (!str) return '';
        return str.replace(/-(\w)/g, function ($0, $1) {
            return $1.toUpperCase()
        })
    }

    //首字母大写
    function capitalizeFirstLetter(str) {
        return str.charAt(0).toUpperCase() + str.slice(1)
    }

    //获取vue的文件名
    function validateFileName(str) {
        return /^\S+\.vue$/.test(str) &&
            str.replace(/^\S+\/(\w+)\.vue$/, (rs, $1) => capitalizeFirstLetter(toCamelCase($1)))
    }
	//vite导入组件的方法
    const requireComponent = import.meta.globEager('./**/*.vue');
    //使用文件内name值列表
    const useDefaultNameList = {};

    //不全局注册列表
    const doNotRegisterList = {};

    //自动注册组件
    const modules = {};
    for (let i in requireComponent) {
    	if(!requireComponent.hasOwnProperty(i)) continue;
        const componentConfig = requireComponent[i];
        let camelCaseName, firstLetter, componentName;
        if (componentConfig.default.name) {
            camelCaseName = toCamelCase(componentConfig.default.name);
            componentName = firstLetter = capitalizeFirstLetter(camelCaseName);
        } else {
            componentName = validateFileName(i)
        }
        if (!(firstLetter && useDefaultNameList[firstLetter])) {
            componentName = validateFileName(i)
        }
        if (modules[componentName]) continue;
        if (!doNotRegisterList[componentName]) {
            Vue.component(componentName, componentConfig.default || componentConfig);
            modules[componentName] = !0;
        }
    }
}

main.js

import { createApp } from 'vue'
import App from './App.vue'
import Components from '@/components/components'
import VueRouter from './my-router'

const app = createApp(App);
//这里使用导入组件
app.use(Components);
//这里使用导入路由
app.use(VueRouter);
app.mount('#app')

请问各位吊大的,有木有更好的方法实现自动导入路由呀!!!

  • 作者:靐齉齾麤龘龖龗鱻爩
  • 原文链接:https://blog.csdn.net/z13540112421/article/details/122969132
    更新时间:2023年1月19日11:26:32 ,共 4034 字。