请求接口设置
.env.development 测试环境
.env.production 发布环境
开启左侧导航栏的Logo
修改src目录下的setting.js的变量 sidebarLogo改为true
然后可在\src\layout\components\Sidebar\Logo.vue data中修改logo图片
-----------这里定义登录用户名的验证函数 这里要进行修改------------
改掉 src/utils/validate.js中方法 validUsername 验证用户名的规则 可以改为
export function validUsername(str) {
// const valid_map = ['admin', 'editor']
// return valid_map.indexOf(str.trim()) >= 0
// 即为输入一个字符即可验证通过
return str.trim().length > 0
}
发送ajax请求 请求拦截 状态码
src/utils/request.js
前端实现动态路由
在src/store/modules/Promission.js 修改asyncRoutes的数据来源
它默认是写死的并且是通过@/router引过来的
所以要将它写活 改为调用后端接口拿到的
给后端定义返回的JSON数据格式:
[{"path":"/permission","component":"#","redirect":"/permission/page","alwaysShow":true,"name":"Permission","meta":{"title":"permission","icon":"lock","roles":["admin","editor"]},"children":[{"path":"/permission/page","name":"PagePermission","meta":{"title":"pagePermission","roles":["admin"]}},{"path":"/permission/directive","name":"DirectivePermission","meta":{"title":"directivePermission"}},{"path":"/permission/role","name":"RolePermission","meta":{"title":"rolePermission","roles":["admin"]}}]},{"path":"/icons","component":"#","children":[{"path":"/icons/index","name":"Icons","meta":{"title":"icons","icon":"icon","noCache":true}}]},{"path":"/example","component":"#","redirect":"/example/list","name":"Example","meta":{"title":"example","icon":"el-icon-s-help"},"children":[{"path":"/example/create","name":"CreateArticle","meta":{"title":"createArticle","icon":"edit"}},{"path":"/example/edit/:id(\\d+)","name":"EditArticle","meta":{"title":"editArticle","noCache":true,"activeMenu":"/example/list"},"hidden":true},{"path":"/example/list","name":"ArticleList","meta":{"title":"articleList","icon":"list"}}]},{"path":"/tab","component":"#","children":[{"path":"/tab/index","name":"Tab","meta":{"title":"tab","icon":"tab"}}]},{"path":"/error","component":"#","redirect":"noRedirect","name":"ErrorPages","meta":{"title":"errorPages","icon":"404"},"children":[{"path":"/error-page/401","name":"Page401","meta":{"title":"page401","noCache":true}},{"path":"/error-page/404","name":"Page404","meta":{"title":"page404","noCache":true}}]},{"path":"/error-log","component":"#","children":[{"path":"/error-log","name":"ErrorLog","meta":{"title":"errorLog","icon":"bug"}}]},{"path":"/excel/","component":"#","redirect":"/excel/export-excel","name":"Excel","meta":{"title":"excel","icon":"excel"},"children":[{"path":"/excel/export-excel","name":"ExportExcel","meta":{"title":"exportExcel"}},{"path":"/excel/select-excel","name":"SelectExcel","meta":{"title":"selectExcel"}},{"path":"/excel/merge-header","name":"MergeHeader","meta":{"title":"mergeHeader"}},{"path":"/excel/upload-excel","name":"UploadExcel","meta":{"title":"uploadExcel"}}]},{"path":"/zip","component":"#","redirect":"/zip/index","alwaysShow":true,"name":"Zip","meta":{"title":"zip","icon":"zip"},"children":[{"path":"/zip/index","name":"ExportZip","meta":{"title":"exportZip"}}]},{"path":"/pdf","component":"#","redirect":"/pdf/index","children":[{"path":"/pdf/index","name":"PDF","meta":{"title":"pdf","icon":"pdf"}}]},{"path":"/pdf/download","hidden":true},{"path":"/theme","component":"#","children":[{"path":"/theme/index","name":"Theme","meta":{"title":"theme","icon":"theme"}}]},{"path":"/clipboard","component":"#","children":[{"path":"/clipboard/index","name":"ClipboardDemo","meta":{"title":"clipboardDemo","icon":"clipboard"}}]},{"path":"/i18n","component":"#","children":[{"path":"/i18n-demo/index","name":"I18n","meta":{"title":"i18n","icon":"international"}}]},{"path":"*","redirect":"/404","hidden":true}]
定义一个transformAsyncRoutes方法
import Layout from '@/layout'
export function transformAsyncRoutes(item) {
const routes = []
for (const route of item) {
const obj = {
path: route.path,
name: route.name,
hidden: route.hidden ? route.hidden : false,
meta: route.meta,
// 如果根目录component为# 导入的则是 Layout
component: route.component === '#' ? Layout : loadView(route.path)
}
// 如果存在redirect这个参数 就赋值 否则什么也不干
route.redirect ? obj.redirect = route.redirect : null
route.children ? obj['children'] = transformAsyncRoutes(route.children) : null
routes.push(obj)
}
return routes
}
// 引入文件
const loadView = (view) => {
// 这里使用import会报错 要改为require
return (res) => require([`@/views${view}`], res)
}
下面要调用这个方法进行数据格式整理并动态导入页面模块 使component字段成为可被路由解析的对象 然后返回一个新的路由表
改写generateRoutes 为:
generateRoutes({ commit }, roles) {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async resolve => {
// 定义一个变量 存放可以访问的路由表
let accessedRoutes
/**
* @param:{ getRoutes } { Function } @description 这是我这边的调用后端接口返回路由列表的方法
*
* 前端实现动态路由需要将asyncRoutes改为从后端进行返回的一个数据 并保持数据格式的对应
* !注意 !:接口请求到的asyncRoutes 为异步操作 需要使用async await改为同步↓
* return new Promise(async resolve => {
* let res = await getRoutes();
* }
*/
const asyncRoutes = await getRoutes()
// 调用transformAsyncRoutes 并把返回的新数组(整理好格式的路由表)赋值给accessedRoutes
const asyncRoutesRes = transformAsyncRoutes(asyncRoutes)
/**
* 如果角色是admin 那么所有的路由表都可以被访问
* 否则的话进行筛选当前角色可以访问的路由表
*/
if (roles.includes('admin')) {
accessedRoutes = asyncRoutesRes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutesRes, roles)
}
// commit提交给SET_ROUTES方法
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
路由列表返回数组对象中的path路径必须在项目目录存在文件(如果没有可以先创建一个空的.vue文件)并且和文件名保持一致 即:

有小伙伴说/error-log对应/error-log/index 其实也没错 因为index.vue可以省略
如果不一致则会报找不到模块的错误 如: app.js:978 Error: Cannot find module './views/icon/index'
发布上线时候 注意 删掉vue.config.js中的 before: require('./mock/mock-server.js')
>>>>>>>END
11
回复了爸爸:
回复了234:
234
234