各位大佬晚上好,由于是后端开发,vue只看过几遍,没有任何vuex、router的概念,我就开始使用pro of vue了。(以下内容纯属瞎得得,可忽略)也是很佩服自己的勇气,但是像我这样的后端开发的同志还有很多。因为前后分离,那就分离的痛快一些,所以想用一些高级的框架😄。可是这个pro并不像我们平时使用的html模版,里面会设计到很多概念。所以今天很大家分享一下pro of vue的启动流程。
下面开始说正题:
在正是开始之前,里面会涉及到vuex或者router的相关内容,如果大家实在不能理解,还是需要大家大致浏览一下官方文档的。
在开发模式下,程序的入口应该是 src/main.js,其中关键的代码
// 这个router对原始router进行了hack注入,方便在开始或结束后调用相应代码,具体实现
// 可以到相应目录查看 这种写法其实是引入 当前目录同级目录router目录中引入 index.js
import router from './router'
new Vue({
router,
store,
created: bootstrap,
render: h => h(App)
}).$mount('#app')
可以看到在此初始化了一个vue的实例,大致的意思就是把router和store渲染到App中去。接下来渲染的话就进入到了src/app.vue文件中了
<template>
<a-locale-provider :locale="locale">
<div id="app">
<router-view/>
</div>
</a-locale-provider>
</template>
可以看到,在模版中只是渲染了router-view组件,而这个router-view就告诉了,Vue Router 在哪里渲染它们。
这样的话,我们的页面就会根据不同的路由进行不同页面的渲染了。
而渲染的内容是实例化的router中的routes属性的值,在 /src/router/index.js中有
import Vue from 'vue'
import Router from 'vue-router'
import { constantRouterMap } from '@/config/router.config' // 一般代表 src/config/router.config.js
// hack router push callback
const originalPush = Router.prototype.push
Router.prototype.push = function push (location, onResolve, onReject) {
if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
return originalPush.call(this, location).catch(err => err)
}
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
})
所以会渲染constantRouterMap具体内容如下:
import { UserLayout, BlankLayout } from '@/layouts'
export const constantRouterMap = [
{
path: '/user',
component: UserLayout,
redirect: '/user/login',
hidden: true,
children: [
{
path: 'login',
name: 'login',
component: () => import(/* webpackChunkName: "user" */ '@/views/user/Login')
},
......................
]
可以看到这其中就包含了我们的登录页面。如果用户此时未登录的话,就会进入登录界面。至于登录的流程大家可以看我另一篇文章。在登录成功之后会有如下代码
this.$router.push({ path: '/' })
这是router的导航方式。push的话可以理解为导航至 / ,具体是什么意思大家参考官方文档。至此我们就进入了项目首页。之前我们有提到过,项目中使用的router是经过hack之后的,所以在router每次操作时其实都会做检查工作,实现的代码在
src/permission.js中,代码如下:
router.beforeEach((to, from, next) => {
NProgress.start() // start progress bar进度条相关
if (Vue.ls.get(ACCESS_TOKEN)) { // 通过token判断是否登录
/* 已经登录并且访问的页面是登录路由的话则跳转到指定连接 */
if (to.path === '/user/login') {
next({ path: '/dashboard/workplace' })
NProgress.done()
} else {
// 如果不是访问的登录页面,则会去获取角色 role(和动态路由有关的值)
// 如果不存在角色
if (store.getters.roles.length === 0) {
// 则去获取角色, store和vuex有关,有需要的同志自行查找
store.dispatch('GetInfo')
.then(res => {
// 获取角色之后
const roles = res.result && res.result.role
// 下面的代码是说 从后端获取用户的路由菜单,动态添加可访问路由表
// 我的代码已经改成了后端获取方式,不同的代码可能稍有不同
store.dispatch('GenerateRoutes', { roles }).then(() => {
// 把已获取到的路由菜单加入到路由表中
router.addRoutes(store.getters.addRouters)
const redirect = decodeURIComponent(from.query.redirect || to.path)
if (to.path === redirect) {
// hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
next({ ...to, replace: true })
} else {
// 跳转到目的路由
next({ path: redirect })
}
})
})
.catch(() => {
notification.error({
message: '错误',
description: '请求用户信息失败,请重试'
})
store.dispatch('Logout').then(() => {
next({ path: '/user/login', query: { redirect: to.fullPath } })
})
})
} else {
next()
}
}
} else {
if (whiteList.includes(to.name)) {
// 在免登录白名单,直接进入
next()
} else {
// 导航至登录页
next({ path: '/user/login', query: { redirect: to.fullPath } })
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
}
}
})
通过上述代码解释,大家应该也知道了,在我们登录操作之前,其实router就已经开始在工作了,登录之后又在获取所有的路由表,从而能够在我们访问不同的连接的时候,进入不同的页面。
就这么多了,晚安everybody,欢迎大家积极讨论,欢迎前端大佬指正。!