diff --git a/src/router/avue-router.js b/src/router/avue-router.js index b424e80..94271a0 100644 --- a/src/router/avue-router.js +++ b/src/router/avue-router.js @@ -8,11 +8,13 @@ RouterPlugin.install = function (vue, router, store, i18n) { this.$store = store; this.$vue = new vue({i18n}); + // 这个的作用是 为了检查出网页链接,因为本项目用到了 iframe function isURL(s) { if (s.includes('html')) return true; return /^http[s]?:\/\/.*/.test(s) } + // 将参数处理为参数的形式拼接 function objToform(obj) { let result = []; Object.keys(obj).forEach(ele => { @@ -83,9 +85,18 @@ RouterPlugin.install = function (vue, router, store, i18n) { return value; }, //动态路由 + // 路由是专门的一个接口获取 + /** + * aMenu: 接受到的动态路由数据 menu的结构外层有父级path 里面有一个childen 记录页面的路由 + * first: 为了区分外界 调用formatRoutes 和 当前文件调用 formatRoutes + */ formatRoutes: function (aMenu = [], first) { + // console.log('aMenu') + // console.log(aMenu) const aRouter = [] + // 获取到全局配置中的 props const propsConfig = this.$website.menu.props; + // 设置 props默认值 作用就是将字段设置成配置的 const propsDefault = { label: propsConfig.label || 'name', path: propsConfig.path || 'path', @@ -93,24 +104,30 @@ RouterPlugin.install = function (vue, router, store, i18n) { children: propsConfig.children || 'children', meta: propsConfig.meta || 'meta', } + // 如果没有权限菜单就结束 if (aMenu.length === 0) return; + // 开始处理menu for (let i = 0; i < aMenu.length; i++) { + // 取到当前要处理的一项 const oMenu = aMenu[i]; + // 判断this.routerList中是否已经存在该path,存在就跳出 if (this.routerList.includes(oMenu[propsDefault.path])) return; + // 这一块的赋值 也就是取到返回的值 let path = (() => { if (first) { + // 将 '/index' 替换为 '' return oMenu[propsDefault.path].replace('/index', '') } else { return oMenu[propsDefault.path] } })(), - //特殊处理组件 + //特殊处理组件 执行完这个 component 也就是精确到具体的文件了 views文件夹下面就是具体的页面代码 component = 'views' + oMenu.path, name = oMenu[propsDefault.label], icon = oMenu[propsDefault.icon], children = oMenu[propsDefault.children], meta = oMenu[propsDefault.meta] || {}; - + // meta中 keepalive 的处理 meta = Object.assign(meta, (function () { if (meta.keepAlive === true) { return { @@ -118,7 +135,7 @@ RouterPlugin.install = function (vue, router, store, i18n) { } } })()); - + //是否有子路由 const isChild = children.length !== 0; const oRouter = { path: path, @@ -140,12 +157,15 @@ RouterPlugin.install = function (vue, router, store, i18n) { icon: icon, meta: meta, redirect: (() => { + // 第一次进来但是没有子路由的 需要添加redirect if (!isChild && first && !isURL(path)) return `${path}/index` else return ''; })(), + // 整理子路由的route 配置 // 处理是否为一级路由 children: !isChild ? (() => { if (first) { + // 这里的isURL判断,因为这个网站有使用 iframe。所以需要判断是否为网页链接 if (!isURL(path)) oMenu[propsDefault.path] = `${path}/index`; return [{ component(resolve) { @@ -159,20 +179,27 @@ RouterPlugin.install = function (vue, router, store, i18n) { } return []; })() : (() => { + /** + * 这里是重点,当有子路由的时候 会再去执行 formatRoutes 方法,然后又会有一个新的 aMenu for循环。 + * 最后返回的是一个数组 aRouter 这个数组就会作为 childen的值被 return + */ return this.formatRoutes(children, false) })() } aRouter.push(oRouter) } + // for循环结束 + // 这个first 卡的其实就是首路由 if (first) { + console.log(aRouter) if (!this.routerList.includes(aRouter[0][propsDefault.path])) { this.safe.$router.addRoutes(aRouter) this.routerList.push(aRouter[0][propsDefault.path]) } } else { + // 这里返回的是子组件 return aRouter } - } } } diff --git a/src/router/router.js b/src/router/router.js index 353e60a..34eb10c 100644 --- a/src/router/router.js +++ b/src/router/router.js @@ -8,16 +8,21 @@ */ import Vue from 'vue'; import VueRouter from 'vue-router'; -import PageRouter from './page/' -import ViewsRouter from './views/' -import AvueRouter from './avue-router'; -import i18n from '@/lang' // Internationalization -import Store from '../store/'; +import PageRouter from './page/' // 页面路由 +import ViewsRouter from './views/' // 页面路由 +import AvueRouter from './avue-router'; //封装的路由控制方法 +import i18n from '@/lang' // Internationalization 国际化 多语言 +import Store from '../store/'; // vuex Vue.use(VueRouter) //创建路由 export const createRouter = () => new VueRouter({ + // https://router.vuejs.org/zh/guide/advanced/scroll-behavior.html#%E5%BC%82%E6%AD%A5%E6%BB%9A%E5%8A%A8 + // 这个方法 是控制滚动条 + // 如果 retuen falsy || {} ,则不发生滚动 scrollBehavior (to, from, savedPosition) { + // savedPosition 这个参数当且仅当导航 (通过浏览器的 前进/后退 按钮触发) 时才可用 效果和 router.go() 或 router.back() if (savedPosition) { + // 返回savedPosition 其实就是 当用户点击 返回的话,保持之前游览的高度 return savedPosition } else { if (from.meta.keepAlive) { @@ -31,11 +36,11 @@ export const createRouter = () => new VueRouter({ }, routes: [...PageRouter, ...ViewsRouter] }) -const Router = createRouter() -AvueRouter.install(Vue, Router, Store, i18n); -Router.$avueRouter.formatRoutes(Store.state.user.menuAll, true); +const Router = createRouter() // 获得 route 实例 +AvueRouter.install(Vue, Router, Store, i18n); // 初始化和注册 AvueRouter +Router.$avueRouter.formatRoutes(Store.state.user.menuAll, true); // 动态路由核心方法 Router.addRoutes([...PageRouter, ...ViewsRouter]); -export function resetRouter () { +export function resetRouter () { // 重置路由 比如用于身份验证失败,需要重新登录时 先清空当前的路有权限 const newRouter = createRouter() Router.matcher = newRouter.matcher // reset router AvueRouter.install(Vue, Router, Store, i18n); diff --git a/vue.config.js b/vue.config.js index 63f734e..c89a258 100644 --- a/vue.config.js +++ b/vue.config.js @@ -28,9 +28,9 @@ module.exports = { proxy: { '/api': { //本地服务接口地址 - target: 'http://localhost', - //远程演示服务地址 - //target: 'https://saber.bladex.vip/api', + // target: 'http://localhost', + //远程演示服务地址 其实官方已经提供了 让vue项目跑起来的服务器连接,好多人不知道这个 + target: 'https://saber.bladex.vip/api', ws: true, pathRewrite: { '^/api': '/'