对于小型点的项目可以这样玩。
代码实现原理就是利用fs和path模块,递归views目录生成vue路由。
//安装 fs和path模块
let fs = require('fs');
const path = require('path');
let root = path.resolve(__dirname, 'src/views')
console.log('开始配置>>>>>>>>>>>>>>>>>>\n')
// 读取文件信息,并生成路由
function readFileInfo(pathName, dirName) {
let routes = [];
let dirDetails = fs.readdirSync(pathName);
let exclude = null;//排除的文件,不生成路由
let excludeDir = null;//排除的目录,不遍历目录
let childList = null;//子路由
if (dirDetails.length == 0) {
return []
}
if (dirDetails.includes('config.json')) {
// 读取json数据
const json = JSON.parse(fs.readFileSync(path.resolve(pathName, 'config.json')))
// 判断是否有exclude属性
const excludeList = json.exclude || [];
const child = json.children || [];
const excludeDirList = json.excludeDir || [];
if (child && child.length > 0) {
// 有配置子路由项
childList = ObjArrDuplicate(child).map((element) => {
if (!element.parent) {
throw new Error('parent属性不能为空 ' + path.resolve(pathName, 'config.json'))
}
const parent = suffixVue([], element.parent)
const list = ArrayDuplicate(suffixVue(element.list));
ArrayDuplicate(list)
// 判断文件是否存在
checkFileExis(list, pathName, 'list属性');
checkFileExis([parent], pathName, 'parent属性');
return {
parent,
list
}
});
}
// 排除的vue文件
if (excludeList && excludeList.length > 0) {
exclude = ArrayDuplicate(suffixVue(excludeList));
checkFileExis(exclude, pathName, 'exclude属性');
}
// 判断排除目录
if (excludeDirList && excludeDirList.length > 0) {
excludeDir = ArrayDuplicate(excludeDirList);
excludeDir.forEach((dir) => {
if (!dirDetails.includes(dir)) {
throw new Error('没有找到目录 ' + path.resolve(pathName, dir) + ',请正确配置exclude属性值')
}
})
}
}
if (exclude && exclude.length != 0) {
// 打印
exclude.forEach((item) => {
console.log('排除生成的路由文件>>>>>>>>>>>>>>>>>>\n', [path.resolve(pathName, item)], '\n')
})
}
// 遍历文件生成对应的路由规则
dirDetails.forEach((item) => {
let is = fs.statSync(path.resolve(pathName, item))
if (is.isFile()) {
if (exclude && exclude.includes(item)) {
// 有排除文件就停止生成路由规则
return
}
const fileInfo = path.parse(item);
let fileName = fileInfo.name;
let suffix = fileInfo.ext;
if (suffix == '.vue') {
const routeName = dirName.split('/').join('-');
let parentName; //fuluyou
// 配置子路由
if (childList && childList.length > 0) {
childList.forEach((child) => {
if (child.parent == item) {
parentName = item;
const { list } = child
const result = list.map(ele => {
// let name = ele.split('.')[0];
let name = ele.substring(0, ele.lastIndexOf('.'));
let hasindex = null;
if (name.includes('./')) {
// 判断是否为路径,只能当前目录下的文件,不能在上一级
name = name.substring(2);
}
if (name[0] == '/') {
throw new Error("请正确设置相对路径 './'或者 ''," + name)
}
const nameInfo = path.parse(name);
if (nameInfo.name == 'index') {
// hasindex = name.substring(0, name.length - 6)
hasindex = nameInfo.dir;
}
return `
{
name:'${routeName ? routeName + '-' : ''}${name.split('/').join('-')}',
path:'${dirName ? '/' + dirName : ''}/${name}',
component:() => import('@/views${dirName ? '/' + dirName : ''}/${hasindex ? hasindex : name + ".vue"}')
}`
})
routes.push(`
{
name:'${routeName ? routeName + '-' : ''}${fileName}',
path:'${dirName ? '/' + dirName : ''}/${fileName}',
component:() => import('@/views${dirName ? '/' + dirName : ''}${fileName != 'index' ? '/' + fileName + '.vue' : ''}'),
children:[${result.join(',')}]
}`)
}
})
// return
}
if (item == parentName) return;
routes.push(`
{
name:'${routeName ? routeName + '-' : ''}${fileName}',
path:'${dirName ? '/' + dirName : ''}/${fileName}',
component:() => import('@/views${dirName ? '/' + dirName : ''}${fileName != 'index' ? '/' + fileName + '.vue' : ''}')
}`)
}
} else {
// 递归遍历
if (excludeDir && excludeDir.includes(item)) {
// 有排除目录就停止生成路由规则
console.log('排除目录>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n', [path.resolve(pathName, item)], '\n')
return
}
// let childDir = readFileInfo(path.resolve(pathName, item), `${dirName ? dirName + '/' : ''}` + item)
let childDir = readFileInfo(path.resolve(pathName, item), `${dirName ? dirName + '/' : ''}` + item)
routes = [].concat(routes, childDir);
}
})
return routes
}
// 加后缀
function suffixVue(list, string) {
if (string) {
let result = (string || '').split('.');
// 安全判断
if (result[result.length - 1] != 'vue') {
// 无文件名后缀 + .vue
return string + '.vue'
} else {
// 有文件名后缀
return string
}
}
return (list || []).map((item) => {
let result = item.split('.');
// 安全判断
if (result[result.length - 1] != 'vue') {
// 无文件名后缀 + .vue
return item + '.vue'
} else {
// 有文件名后缀
return item
}
})
}
// 检查文件是否存在
function checkFileExis(list, pathName, string) {
list.forEach((item) => {
const is = fs.existsSync(path.resolve(pathName, item))
if (!is) {
throw new Error("文件不存在" + path.resolve(pathName, item) + ",请正确配置" + string + "值")
}
})
}
// 数组去重
function ArrayDuplicate(array) {
let arr = [...new Set(array)]
return arr;
}
// 对象数组去重
function ObjArrDuplicate(array) {
let list = ArrayDuplicate(array.map(item => JSON.stringify(item))).map(item => JSON.parse(item));
// 判断属性是否唯一
checkAttr(list)
return list
}
// 判断属性是否唯一
function checkAttr(list) {
let length = list.length;
// parent属性
for (let i = 0; i < length - 1; i++) {
for (let k = i + 1; k < length; k++) {
if (list[i].parent == list[k].parent) {
throw new Error('children中parent属性不能相同,' + list[i].parent)
}
// list值
list[k].list.forEach(item => {
if (list[i].list.includes(item)) {
throw new Error('children中list列表值不能相同,' + item)
}
})
}
}
// list
}
// 转化为字符串
function toStringFormat(value) {
return `export let Routes = [${value.join(",")}];`
}
// 生成文件
fs.writeFile('./src/router/config.js', toStringFormat(readFileInfo(root, '')), (err) => {
if (err) return
console.log('配置成功 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n')
})
以上代码文件保存为 quick-route-generation.js
1.安装 npm i fs path -D。
2.将此代码文件放在scr同级目录下。
3.运行:node quick-route-generation.js ,生成的路由规则在src/router/config.js中。
4.使用路由规则:在/src/router/index.js中使用。
import { Routes } from './config'
import Vue from 'vue';
import VueRouter from 'vue-router'
import { Routes } from './config'
Vue.use(VueRouter);
const routes = [];
const router = new VueRouter({
routes
})
router.addRoutes(Routes);
例子以及配置:
(一)默认情况下会遍历views文件下的所有文件生成路由。
1.views下面有两个文件夹,test和test-two,运行node router.config.js.
目录结构:
运行代码结果如下:
2.views下面有两个文件夹,test和test-two,test目录下有test-child文件夹。
目录结构:
运行代码结果如下:完全生成
(二)默认情况下会遍历views文件下的所有文件生成路由,但是可以在要生成路由的对应目录下添加config.json文件配置,不生成路由的文件和目录。
在views目录下添加config.json文件,如图目录结构所示。
config.json内容如下: exclude属性值和excludeDir属性值只能写当前目录下的目录名或文件名,文件名可以省略“.vue”后缀名。
{
"exclude": [
"index"
],
"excludeDir": [
"test"
]
}
因为排除了views目录下的index.vue和test目录,所以不会生成路由。
运行代码:
(三)生成子路由配置config.json
目录结构:新增views下面的child目录,child下面有index.vue文件来生成子路由以及src/views/index.vue文件生成子路由
config.json属性值配置如下:
children属性是个数组值类型,里面是个对象数组。对象有两个属性parent和list。vue文件都可省略后缀“.vue”。
”parent”属性必须填,值为当前目录下的vue文件,且exclude属性值中不能再写parent属性值。
list属性值是数组,数组每项值为当前目录下的vue文件,也可以是当前目录下的子目录(孙子目录...等)下的vue文件。
list数组每项值如果是路径则排除第一级的目录,exclude属性值中要写上目录名,不生成路由,如果是当前目录下的vue文件,则排除vue文件,exclude属性值中要写上vue文件名,不让它生成路由。如果这样写,后果就是路由重复,会有警告信息。
json配置如下:
①第一种config.json
{
"exclude": [
"index"
],
"excludeDir": [
"test",
"child"
],
"children": [
{
"parent": "parent.vue",
"list": [
"./child/index.vue",
"./index.vue"
]
}
]
}
②第二种config.json
{
"exclude": [
"index"
],
"excludeDir": [
"test",
"child"
],
"children": [
{
"parent": "parent",
"list": [
"./child/index",
"./index"
]
}
]
}
③第三种config.json
{
"exclude": [
"index"
],
"excludeDir": [
"test",
"child"
],
"children": [
{
"parent": "parent",
"list": [
"child/index",
"index"
]
}
]
}
运行代码,三种情况结果都一样,如下:
最后,config.json不一定放在views下面,也可以在views中的其它目录下,一个目录下只能有一个config.json。
最新代码:
let fs = require('fs');
const path = require('path');
let root = path.resolve(__dirname, 'src/views')
console.log('开始配置>>>>>>>>>>>>>>>>>>\n')
// 读取文件信息,并生成路由
function readFileInfo(pathName, dirName) {
let routes = [];
let dirDetails = fs.readdirSync(pathName);
let exclude = null;//排除的文件,不生成路由
let excludeDir = null;//排除的目录,不遍历目录
let childList = null;//子路由
let optionsAttr = null;
let optionsKeys = [];
let paramsAttr = null;
let paramsKeys = [];
if (dirDetails.length == 0) {
return []
}
if (dirDetails.includes('config.json')) {
// 读取json数据
const json = JSON.parse(fs.readFileSync(path.resolve(pathName, 'config.json')))
// 判断是否有exclude属性
const excludeList = json.exclude || [];
const child = json.children || [];
const excludeDirList = json.excludeDir || [];
const options = json.options || {};
const params = json.params || {};
// 子路由
if (child && child.length > 0) {
// 有配置子路由项
childList = ObjArrDuplicate(child).map((element) => {
if (!element.parent) {
throw new Error('parent属性不能为空 ' + path.resolve(pathName, 'config.json'))
}
const parent = suffixVue([], element.parent);
const list = ArrayDuplicate(suffixVue(element.list));
const optionsChildAttr = optionsAttrToName(optionSuffix(element.options || {}));
const optionsChildKeys = Object.keys(optionsChildAttr);
const paramsChildAttr = optionsAttrToName(optionSuffix(element.params || {}));
// console.log(paramsChildAttr);
const paramsChildKeys = Object.keys(paramsChildAttr);
ArrayDuplicate(list)
// 判断文件是否存在
checkFileExis(list, pathName, 'list属性');
checkFileExis([parent], pathName, 'parent属性');
// checkFileExis(paramsChildKeys, pathName, 'params属性');
return {
parent,
list,
optionsChildAttr,
optionsChildKeys,
paramsChildAttr,
paramsChildKeys
}
});
}
// 排除的vue文件
if (excludeList && excludeList.length > 0) {
exclude = ArrayDuplicate(suffixVue(excludeList));
checkFileExis(exclude, pathName, 'exclude属性');
}
// 判断排除目录
if (excludeDirList && excludeDirList.length > 0) {
excludeDir = ArrayDuplicate(excludeDirList);
excludeDir.forEach((dir) => {
if (!dirDetails.includes(dir)) {
throw new Error('没有找到目录 ' + path.resolve(pathName, dir) + ',请正确配置exclude属性值')
}
})
}
// 配置路由数据options
if (JSON.stringify(options) != '{}' && options) {
optionsAttr = optionSuffix(options);
optionsKeys = Object.keys(optionsAttr);
// console.log('optionsAttr', optionsAttr, optionsKeys)
}
// 配置路由params
if (JSON.stringify(params) != '{}' && params) {
paramsAttr = optionSuffix(params);
paramsKeys = Object.keys(paramsAttr);
}
}
if (exclude && exclude.length != 0) {
// 打印
exclude.forEach((item) => {
console.log('排除生成的路由文件>>>>>>>>>>>>>>>>>>\n', [path.resolve(pathName, item)], '\n')
})
}
// 遍历文件生成对应的路由规则
dirDetails.forEach((item) => {
let is = fs.statSync(path.resolve(pathName, item))
if (is.isFile()) {
if (exclude && exclude.includes(item)) {
// 有排除文件就停止生成路由规则
return
}
const fileInfo = path.parse(item);
let fileName = fileInfo.name;
let suffix = fileInfo.ext;
if (suffix == '.vue') {
const routeName = dirName.split('/').join('-');
let paramsResult = '';
if (paramsKeys.includes(fileName + ".vue")) {
let arr = paramsAttr[(fileName + ".vue")];
arr.unshift("")
paramsResult = arr.join('/:')
}
let parentName; //fuluyou
// 配置子路由
if (childList && childList.length > 0) {
childList.forEach((child) => {
// console.log(child)
if (child.parent == item) {
parentName = item;
const { list, optionsChildAttr, optionsChildKeys, paramsChildKeys, paramsChildAttr } = child;
// if (optionsChildAttr && JSON.stringify(optionsChildAttr) !== '{}') {
// // console.log('child', optionsChildAttr, optionsChildKeys, list)
// }
const result = list.map(ele => {
// let name = ele.split('.')[0];
let name = ele.substring(0, ele.lastIndexOf('.'));
let hasindex = null;
if (name.includes('./')) {
// 判断是否为路径,只能当前目录下的文件,不能在上一级
name = name.substring(2);
}
if (name[0] == '/') {
throw new Error("请正确设置相对路径 './'或者 ''," + name)
}
const nameInfo = path.parse(name);
if (nameInfo.name == 'index') {
// hasindex = name.substring(0, name.length - 6)
hasindex = nameInfo.dir;
}
let paramsResultChild = '';
if (paramsChildKeys.includes(name)) {
let arr = paramsChildAttr[name];
arr.unshift("")
paramsResultChild = arr.join('/:')
}
if (optionsChildKeys.includes(name)) {
return `
{
name:'${routeName ? routeName + '-' : ''}${name.split('/').join('-')}',
path:'${dirName ? '/' + dirName : ''}/${name}${paramsResultChild}',
component:() => import('@/views${dirName ? '/' + dirName : ''}/${hasindex ? hasindex : name + ".vue"}'),
${run(optionsChildAttr[name])}
}`
}
return `
{
name:'${routeName ? routeName + '-' : ''}${name.split('/').join('-')}',
path:'${dirName ? '/' + dirName : ''}/${name}${paramsResultChild}',
component:() => import('@/views${dirName ? '/' + dirName : ''}/${hasindex ? hasindex : name + ".vue"}')
}`
})
// 判断是否有父路由的属性
let key = parentName.substring(0, parentName.lastIndexOf('.')), value = ''
if (optionsChildKeys.includes(key)) {
value = run(optionsChildAttr[key])
}
// fuluyou的options
if (optionsKeys.includes(fileName + ".vue")) {
routes.push(`
{
name:'${routeName ? routeName + '-' : ''}${fileName}',
path:'${dirName ? '/' + dirName : ''}/${fileName}${paramsResult}',
component:() => import('@/views${dirName ? '/' + dirName : ''}${fileName != 'index' ? '/' + fileName + '.vue' : ''}'),
${run(optionsAttr[fileName + '.vue'])},
${value ? value + ",\n" : ""}children:[${result.join(',')}]
}`)
return
}
routes.push(`
{
name:'${routeName ? routeName + '-' : ''}${fileName}',
path:'${dirName ? '/' + dirName : ''}/${fileName}${paramsResult}',
component:() => import('@/views${dirName ? '/' + dirName : ''}${fileName != 'index' ? '/' + fileName + '.vue' : ''}'),
${value ? value + ",\n" : ""}children:[${result.join(',')}]
}`)
}
})
// return
}
if (item == parentName) return;
// 无子路由的路由规则
if (optionsKeys.includes(fileName + ".vue")) {
routes.push(`
{
name:'${routeName ? routeName + '-' : ''}${fileName}',
path:'${dirName ? '/' + dirName : ''}/${fileName}${paramsResult}',
component:() => import('@/views${dirName ? '/' + dirName : ''}${fileName != 'index' ? '/' + fileName + '.vue' : ''}'),
${run(optionsAttr[fileName + '.vue'])}
}`)
return
}
routes.push(`
{
name: '${routeName ? routeName + '-' : ''}${fileName}',
path: '${dirName ? '/' + dirName : ''}/${fileName}${paramsResult}',
component: () => import('@/views${dirName ? '/' + dirName : ''}${fileName != 'index' ? '/' + fileName + '.vue' : ''}'),
} `)
}
} else {
// 递归遍历
if (excludeDir && excludeDir.includes(item)) {
// 有排除目录就停止生成路由规则
console.log('排除目录>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n', [path.resolve(pathName, item)], '\n')
return
}
// let childDir = readFileInfo(path.resolve(pathName, item), `${ dirName ? dirName + '/' : '' } ` + item)
let childDir = readFileInfo(path.resolve(pathName, item), `${dirName ? dirName + '/' : ''}` + item)
routes = [].concat(routes, childDir);
}
})
return routes
}
// 生成路由配置options中的路由规则字符串
function run(obj) {
let result = ``;
let keys = Object.keys(obj);
let values = Object.values(obj);
for (let i in keys) {
let value = values[i]
if (typeof value == 'object') {
value = `{${run(value)}}`
}
if (typeof value == 'string' && !value.includes('{') && !value.includes('}')) {
value = "'" + value + "'"
}
if (i == keys.length - 1) {
result = result + `${keys[i]}:${value}`
} else {
result = result + `${keys[i]}:${value},
`
}
}
return result
}
// 跟child options属性值中的name一致
function optionsAttrToName(Obj) {
let attrList = Object.keys(Obj);
let result = {};
for (let i in attrList) {
let value = Obj[attrList[i]];
let key = attrList[i];
let name = key.substring(0, key.lastIndexOf('.'));
if (name.includes('./')) {
// 判断是否为路径,只能当前目录下的文件,不能在上一级
name = name.substring(2);
}
if (Reflect.has(result, name)) {
throw new Error("配置项属性值不能相同》》》" + key)
}
result[name] = value;
}
return result
}
// options配置加后缀
function optionSuffix(Obj) {
let attrList = Object.keys(Obj);
let result = {};
for (let i in attrList) {
let value = Obj[attrList[i]];
let key = attrList[i];
if (key.indexOf('./') == 0) {
key = key.slice(2);
}
if (key.indexOf('/') == 0 || key.indexOf("../") == 0) {
throw new Error("不能写绝对路径/或 ../" + key)
}
key = suffixVue([], key);
// 是否唯一,不唯一报错
if (Reflect.has(result, key)) {
throw new Error("配置项属性值不能相同》》》" + key)
}
result[key] = value;
}
return result
}
// 加后缀
function suffixVue(list, string) {
if (string) {
let result = (string || '').split('.');
// 安全判断
if (result[result.length - 1] != 'vue') {
// 无文件名后缀 + .vue
return string + '.vue'
} else {
// 有文件名后缀
return string
}
}
return (list || []).map((item) => {
let result = item.split('.');
// 安全判断
if (result[result.length - 1] != 'vue') {
// 无文件名后缀 + .vue
return item + '.vue'
} else {
// 有文件名后缀
return item
}
})
}
// 检查文件是否存在
function checkFileExis(list, pathName, string) {
list.forEach((item) => {
const is = fs.existsSync(path.resolve(pathName, item))
if (!is) {
throw new Error("文件不存在" + path.resolve(pathName, item) + ",请正确配置" + string + "值")
}
})
}
// 数组去重
function ArrayDuplicate(array) {
let arr = [...new Set(array)]
return arr;
}
// 对象数组去重
function ObjArrDuplicate(array) {
let list = ArrayDuplicate(array.map(item => JSON.stringify(item))).map(item => JSON.parse(item));
// 判断属性是否唯一
checkAttr(list)
return list
}
// 判断属性是否唯一
function checkAttr(list) {
let length = list.length;
// parent属性
for (let i = 0; i < length - 1; i++) {
for (let k = i + 1; k < length; k++) {
if (list[i].parent == list[k].parent) {
throw new Error('children中parent属性不能相同,' + list[i].parent)
}
// list值
list[k].list.forEach(item => {
if (list[i].list.includes(item)) {
throw new Error('children中list列表值不能相同,' + item)
}
})
}
}
// list
}
// 转化为字符串
function toStringFormat(value) {
return `export let Routes = [${value.join(",")}
]; `
}
// 生成文件
fs.writeFile('./src/router/config.js', toStringFormat(readFileInfo(root, '')), (err) => {
if (err) return
console.log('配置成功 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n')
})
2022年10月25日更新:
可以配置路由数据,如下结果所示。
只需在config.json中加入属性options:
{
"options": {
"index.vue": {
"meta": {
"title": "登录"
}
}
}
}
解释:options中配置对应的vue文件(index.vue)生成的路由数据,然后在属性值“index.vue”中添加想要的路由数据即可。
详情配置可以查看下面的config.json文件的所有配置。
2022年11月3日更新:可以添加params路由参数
views目录结构如下:
config.json(上图选中的部分)配置如下(含注释):
{
"****注释!!!!****":"针对当前的目录内有效或配置的子路由目录",
"****注释****":"子路由配置一定要把目录排除了,没有排除的目录只能为空数组,不能写相对路径,只能写目录名",
"excludeDir":["child","round-child"],
"***********注释*******":"排除文件,可以省略 .vue后缀,不能用相对路径只能写文件名,没有排除的文件只能为空数组",
"exclude":[],
"***********注释1*******":"配置路由数据,可省略 .vue后缀,可相对路径",
"options": {
"./index": {
"meta": {
"title": "登录"
}
},
"./round.vue":{
"meta":"round"
}
},
"***********注释3*******":"配置路由参数,可省略 .vue后缀,可相对路径",
"params":{
"./index.vue":["id","name"],
"round":["id","name","age"]
},
"***注释***":"子路由配置 optios是路由额外数据,pramas是路由参数",
"children":[
{
"***********注释*******":"父路由组件,不能写相对路径,只能写文件名,可省略 .vue后缀",
"parent":"index.vue",
"***********注释1*******":"子路由组件列表",
"****注释****":"子路由配置一定要把目录child排除了,可省略 .vue后缀,可写相对路径",
"list":["./child/test.vue","./child/test-one.vue","./child/child-child/index.vue"],
"*******注释****":"配置路由数据",
"options":{
"*****注释******":"属性与以上list列表值相同",
"./child/test.vue":{"meta":{"title":"title"}},
"./child/test-one.vue":{"meta":"title"},
"./child/child-child/index":{"a":"a"}
},
"*******注释*****":"配置路由参数",
"params":{
"*****注释******":"属性与以上list列表值相同,值为数组列表表示动态params参数",
"./child/test.vue":["test","test1"],
"./child/test-one.vue":["test-one","test-one1"],
"./child/child-child/index":["test-one","test-one1"]
}
},
{
"parent":"round",
"list":["round-child/index","./round-child/index1"],
"options": {
"round-child/index": {"meta":{"title":"round-child/index"}}
},
"params": {
"round-child/index":["round"]
}
}
]
}
用node运行代码生成js文件结果如下(代码在最下面):
export let Routes = [
{
name: 'home-index',
path: '/home/index',
component: () => import('@/views/home'),
meta: { title: '首页' }
},
{
name: 'Layx',
path: '/Layx',
component: () => import('@/views/Layx.vue'),
},
{
name: 'login-index',
path: '/login/index/:id/:name',
component: () => import('@/views/login'),
meta: { title: '登录' },
children: [
{
name: 'login-child-test',
path: '/login/child/test/:test/:test1',
component: () => import('@/views/login/child/test.vue'),
meta: { title: 'title' }
},
{
name: 'login-child-test-one',
path: '/login/child/test-one/:test-one/:test-one1',
component: () => import('@/views/login/child/test-one.vue'),
meta: 'title'
},
{
name: 'login-child-child-child-index',
path: '/login/child/child-child/index/:test-one/:test-one1',
component: () => import('@/views/login/child/child-child'),
a: 'a'
}]
},
{
name: 'login-round',
path: '/login/round/:id/:name/:age',
component: () => import('@/views/login/round.vue'),
meta: 'round',
children: [
{
name: 'login-round-child-index',
path: '/login/round-child/index/:round',
component: () => import('@/views/login/round-child'),
meta: { title: 'round-child/index' }
},
{
name: 'login-round-child-index1',
path: '/login/round-child/index1',
component: () => import('@/views/login/round-child/index1.vue')
}]
}
];
通过以上json配置就能生成想要的路由规则了。