vue路由文件自动化处理

你还在一个个路由文件引入而烦恼吗

你还被别人说,你只是一个只会ctrl+ c ctrl +v的码仔吗

可是

做个与世无争的垃圾不好吗

在这里插入图片描述

global.ts


//  可以把检测的类型去掉,转成js

// 关键在于  require.context

// 暴露了两个方法 在组件声明两个变量来区别状态 isRouter  isComponent

import Vue from "vue";

// 获取component下所有vue文件
function getComponent() {
  return require.context("../components", true, /\.vue$/);
}
// 获取views下所有vue文件
function getRouterComponent() {
  return require.context("../views", true, /\.vue$/);
}

// 首字母转换大写
function viewToUpperCase(str: string) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}
// 首字母转换小写
function viewToLowerCase(str: string) {
  return str.charAt(0).toLowerCase() + str.slice(1);
}

export const vueComponent = () => {
  // 获取文件全局对象  isComponent
  const requireComponents = getComponent();
  requireComponents.keys().forEach((fileSrc: string) => {
    const fileName = requireComponents(fileSrc);
    const file = fileName.default.options;
    const componentName = file.name;
    if (fileName.default.isComponent) { // 判断是不是组件
      Vue.component(componentName, fileName.default || fileName);
    }
  });
};

export const vueRouters = () => {
  // 获取路由文件 isRouter
  const routerList: any = [];
  const requireRouters = getRouterComponent();
  requireRouters.keys().forEach((fileSrc: string) => {
    // 获取 components 文件下的文件名
    const viewSrc = requireRouters(fileSrc);

    const file = viewSrc.default.options;
    // 首字母转大写
    const vueRouterUpper = viewToUpperCase(file.name);
    // 首字母转小写
    const vueRouterLower = viewToLowerCase(file.name);
    // 设置路由路由路径
    const fileNameSrc = fileSrc.replace(/^\.\//, "");
    // 是否自动注册路由依据每个文件里的 isRouter 属性 避免注册不用的路由
    if (viewSrc.default.isRouter) { // 判断是不是路由文件
      // 注册路由
      routerList.push({
        path: `/${vueRouterLower}`,
        name: `${vueRouterUpper}`,
        component: () => import(`@/views/${fileNameSrc}`),
        meta: {
          index: 1
        }
      });
    }
  });
  return routerList;
};

export default class Home extends Vue {
  static isRouter: boolean = true;
 }
export default class Home extends Vue {
  static isComponent: boolean = true;
 }

组件在main.js使用

import { vueComponent } from "./utils/global";
vueComponent()

路由在router.js使用

import { vueRouters } from "../utils/global";

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/",
      redirect: "/home"
    },
    ...vueRouters()
  ]
});

简单的路由,组件模块是可以这样秀一波了

我原本以为:牛* 啊,好* 啊。以后项目就这样搞。可是,今天作项目的时候,我二级路由,参数:id这些方案怎么破

一切又感觉回到了起点(组件注册可以)

在git上找到两个,附上地址
https://github.com/zhangOking/vuecli3plugin-generatererouter
https://github.com/18692959234/free-router

以下是其中一个上大佬的,仿照nuxt.js

route/route.js

// import Vue from 'vue'
let files = require.context('../pages', true, /\.vue$/) // 根据目录结构去搜索文件
let filesKey = files.keys() // 获取整个目录结构
console.log(filesKey)
/**
 * 获取路由name
 * @param {*} file type:string (文件完整的目录)
 */
const getRouteItemName = (file) => {
  let match = file.match(/\/(.+?)\.vue$/)[1] // 去除相对路径与.vue
  let res = match.replace(/_/ig, '').replace(/\//ig, '-') // 把下划线去除, 改变/为-拼接
  return res
}

/**
 * 获取路由path
 * @param {*} file String (目录,一级路由则为完整目录,多级为自身目录名称)
 */
const getRouteItemPath = (file) => {
  return file.replace('/index.vue', '').replace('index.vue', '').replace('vue', '').replace(/_/g, ':').replace(/\./g, '')
}

/**
 * 注册组建
 * @param {*} componentConfig (即为调用files方法得出的componentConfig)
 */
// const registerComponent = (componentConfig) => Vue.component(componentConfig.default.name || componentConfig.default, componentConfig.default || componentConfig)

/**
 * 校验目录下是否有其他文件,注意((?!${name}).)是因为要查询的目录有可能为name/name.vue,而这样可能会导致误判有无children,所以要匹配非name。
 * @param {*} file type:string (当前目录路径)
 * @param {*} name type:string (目录的文件名 默认等于file参数)
 */
const hasfile = (file, name = file) => new RegExp(file + `/((?!${name}).)`)

/**
 * 校验.vue文件
 * @param {*} file type:string (当前目录路径)
 */
const hasVue = (file) => new RegExp(file + '.vue')

/**
 * 构建路由
 * @param {*} map type:Object
 */
const getRoutes = (map) => {
  let res = []
  for (let key in map) { // 遍历对象
    let level = map[key] // 取出对应value
    let text = level.join('@') // 用@把分级数组拼接,这样只是为了方便查找
    let expr1 = hasfile(key) // 校验规则,有无子文件
    let expr2 = hasVue(key) // 校验规则,有无vue文件
    let route = {} // 初始化route
    if (text.match(expr1) && text.match(expr2)) { // 有children的route
      let max = Math.max(...level.map(v => v.match(/\/(.+?).vue$/)[1].split('/').length)) // 找目录里最深的层级数
      let i = 0 // 标记层级
      while (i++ < max) { // 按层级来搭建route
        level.forEach((item) => {
          let wipeOfVue = item.match(/\/(.+?).vue$/)[1] // 匹配纯路径,去除相对路径与.vue
          let classArray = wipeOfVue.split('/') // 切割为了方便操作
          let len = classArray.length // 深度
          if (len === i) {
            if (i === 1) { // 如果为第一层,则必带有children
              route = {
                component: files(item).default,
                path: getRouteItemPath(item),
                children: []
              }
            } else {
              let file = item.match(/(.+?)\.vue$/)[1] // 只匹配目录下.vue之前的路径
              let name = classArray[len - 1] // 获取每个路径下具体的文件名
              let iteration = classArray.slice(0, len - 1) // 截取文件路径
              let childRoute = {
                component: files(item).default,
                path: getRouteItemPath(name)
              }
              // 从文件的目录下搜索有无子文件,有子文件代表有children属性。 否则无,则直接给route增加name属性
              text.match(hasfile(file, name)) && text.match(hasVue(file)) ? childRoute.children = [] : childRoute.name = getRouteItemName(item)

              // 通过截取的目录找到对应的parent
              let parent = iteration.reduce((map, current, index) => {
                let path = index === 0 ? getRouteItemPath(`/${current}.vue`) : getRouteItemPath(`${current}.vue`)
                return map.filter(v => v.path === path)[0].children
              }, [route])
              parent && parent.push(childRoute)
            }
          }
        })
      }
      res.push(route) // 添加route对象
    } else { // 没有children,直接遍历插入
      level.forEach(item => {
        route = {
          component: files(item).default,
          name: getRouteItemName(item),
          path: getRouteItemPath(item)
        }
        res.push(route) // 添加route对象
      })
    }
  }
  return res // 返回整个route对象
}

/**
 * 以一级文件或者文件夹 分类获取路由
 */
const createClassify = () => {
  let map = filesKey.reduce((map, cur) => {
    let dislodge = cur.match(/\/(.+?)\.vue$/)[1] // 只匹配纯文件名的字符串
    let key = dislodge.split('/')[0]; // 拿到一级文件的名称
    (map[key] || (map[key] = [])).push(cur)
    return map
  }, {})
  return getRoutes(map)
}

const freeRoute = createClassify()
console.log(freeRoute)
const routes = [
  ...freeRoute
]

export default routes

route/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router
还有多少兄弟姐妹还在岗位上的,注意防护,安全出行
回家第一天,可能就已经被爸妈嫌弃了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值