vue-router 路由自动生成

在传统前端开发中,通常会在 src 下维护两个文件夹:

  • view:存放视图 vue 文件
  • router:存放路由模块 js 文件

但是我在工作中总感觉怪怪的,因为这两个东西存在太多相似的地方,甚至有些项目的这两个文件夹的结构存在一一对应的关系,增加一个视图页面就要增加一个路由,减少一个视图也要减少一个路由。

倘若项目规模变大后,同时维护这两个文件夹将变得越来越困难。

所以我想通过 require.context 机制根据 view 的目录结构动态生成一个对应的 VueRouter 对象,这样就不用在改变视图的时候再去修改路由了。下面是我的源码:

// main.js
import Vue from 'vue'
import view from './view'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

Vue.config.productionTip = false

function handleKey(ctx, key, mode) {
  let fullpath
  if (mode == 0) {
    fullpath = key.substring(2, key.length-10)
  } else {
    fullpath = key.substring(2, key.length-4)
  }
  let cut = fullpath.split("/")
  if (cut.length == 1) {
    routes.push(createRoute(ctx(key), "/"+fullpath))
  } else {
    let parent = routes.find(obj => {
      if (obj.path == "/"+cut[0]) return obj
    })
    for (let i = 1; i < cut.length-1; i++) {
      parent = parent.find(obj => {
        if (obj.path == cut[i]) return obj
      })
    }
    if (parent.children == undefined) parent.children = []
    parent.children.push(createRoute(ctx(key), cut[cut.length-1]))
  }
}

function createRoute(component, path) {
  let route = {}
  if (component.route !== undefined) {
    route = component.route
  }
  route.path = path
  route.component = component.default
  return route
}

const routes = []

// index vue
const indexvue = require.context("./view", true, /\/index\.vue$/)
indexvue.keys().sort().forEach(key => {
  if (key === "./index.vue") return
  handleKey(indexvue, key, 0)
})

// other vue
const othervue = require.context("./view", true, /\.vue$/)
othervue.keys().forEach(key => {
  if (/\/index\.vue$/.test(key)) return
  handleKey(othervue, key, 1)
})

const router = new VueRouter({
  mode: 'history',
  routes
})

new Vue({
  router,
  render: h => h(view),
}).$mount('#app')

为了使上面的程序良好运行,需要遵循几个要求:

  • view 目录下的 index.vue 是整个项目的入口,记得在里面加上 id="app"
  • 在 view 目录及子目录中,存在对应的 index.vue 视图,该视图通常被用来渲染同目录下的非 index 视图,所以需要加上 <router-view/>,该视图对应的自动生成的路由为相对 view 目录的路径,比如,要访问 view/path1/path2/index.vue ,对应的路由为 /path1/path2
  • 对于非 index 视图,其自动生成的路由为相对路径加上文件名,比如,要访问 view/path1/path2/hello.vue,对应的路由就是 /path1/path2/hello
  • 自动生成的路由只包含 path 和 component 属性,如果有其他属性需求,可以在 vue 文件内部暴露一个 route 对象,这样我觉得更好维护,比如:
<template>...</template>
<script>
export default {
  ...
}
export let route = {
  redirect: "xx"
}

这种自动生成的路由也有一定的局限性,它不支持动态路由参数,只支持哪些路由和文件夹结构一一对应的项目。

源码可能会有 bug ,如有需要可以交流一下。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容