VueRouter
注意搭建项目的时候需勾选路由
1 配置路由与使用
将路由文件单独用一个router文件夹下index.js,在此文件进行配置,实现结构化项目
import Vue from 'vue'
import Login from '@/views/Login'
const routes = [
{
// 404 界面
name: "notFound",
path: '*',
component: () => import("@/views/NotFound")//懒加载
},
{
name: "login",
path: '/login',
component: Login
},
{
name: "main",
path: '/',
component: Main,
redirect:"order", //重定向
children: [ //嵌套路由 , 不写/, 在子路由前面加上父级路由地址便是完整地址
{
name: "order",
path: "order",
component: () => import("@/views/Order")
},
{// 文章管理
name: "articleManager",
path: "sysManager/articleManager",
component: () => import("@/views/ArticleManager"),
}
]
}
]
//创建路由
const router = new VueRouter({
routes
})
export default router
然后再main.js进行引入
import App from './App.vue'
import router from './router'
new Vue({
axios,
router, //这里就是引入路由
store,
render: h => h(App)
}).$mount('#app')
配置路由出口,即路由显示的位置
<!-- 路由出口 -->
<router-view></router-view>
验证,在浏览器输入项目地址加上路由地址,能成功访问便是配置成功
2 路由跳转
api跳转
//通过path跳页面
this.$router.push("/layout/admin")
//通过path跳页面
this.$router.push({
path: "/layout/admin"
})
//通过名称跳转页面
this.$router.push({
name: 'Admin'
})
通过router-link跳转页面
<router-link to="/layout/order" active-class="acMenu" class="unacMenu">订单</router-link>
说明:
- to设置要跳转的页面路径,该路径必须在路由中配置过
- active-class设置当前路由激活状态的样式。
ui库element-ui
使用element-ui的菜单,menu上设置 router,index就是跳往的地址
<el-menu router class="el-menu-vertical-demo" background-color="#545c64" text-color="#fff" ctive-text-color="#ffd04b">
<!-- index属性值是路由地址便可跳转对应页面 -->
<el-menu-item index="/layout/order">
订单
</el-menu-item>
3 路由传参
问号传参(get传参),优先考虑
//需要传递参数的页面进行传参,
showDetail(row) {
this.$router.push({
path: `/layout/orderDetail?id=${row.id}`
})
}
//在对应页面接收参数的页面
created() {
//获取地址栏问号传参 $route.query.id
console.log(this.$route.query.id, 333);
}
说明:
- 在url地址后面使用问号的方式即可传参。例:?id=1&name=2
- 通过$router.query可以取出地址栏问号传递的参数。query对象会将所有的参数名做为对象属性名称,参数值做为属性对应的值放入。
query传参
//需要传递参数的页面进行传参
this.$router.push({
path: `/layout/orderDetail`,
query: {
id: row.id,
reciveUserName: row.reciveUserName
}
})
//在对应页面接收参数的页面
created() {
//获取地址栏问号传参
console.log(this.$route.query.id, 333);
}
说明:
- $router.push方法的参数中,可以加入query属性。该属性是一个对象类型。对象的属性名称即是参数名称,属性的值即是参数值
- query传参只是将push方法中的query对象解析到地址栏,并用问号拼接起来。它主要的作用是解决问号传参时拼接字符串时比较麻烦,当参数多的时候字符串拼接容易出错,此时可以借助query传参。
params传参,不推荐
//需要传递参数的页面进行传参
this.$router.push({
name: "OrderDetail",// 只能使用name
params: {
id: row.id,
reciveUserName: row.reciveUserName
}
//在需要接收参数的页面
created() {
//获取地址栏params传参
console.log(this.$route.params.id, 333)
}
说明:
- params传参,只能和name跳转页面配套使用
- 取参数使用$router.params来获取参数
- params传参,页面刷新会导致参数丢失
动态路由传参,不推荐使用
//配置动态路由
{
//动态路由配置
name: 'OrderDetail',
path: 'orderDetail/:id?/:name?,
//懒加载订单页面
component: () => import("@/views/OrderDetail"),
//打开属性接收参数的开关
props: true
}
//需要传递参数的页面进行传参
this.$router.push(`/layout/orderDetail/${row.id}/${row.reciveUserName}`);
//在需要接收参数的页面
props: {
id: {
type: String,
default: ""
},
name: {
type: String,
default: ""
}
},
//也可以
created() {
//获取地址栏params传参
console.log(this.$route.params.id, 333)
}
说明:
- 在路由配置对象中,给path加上/:id来配置动态路由,其中id将会做为参数名称放入params对象中
- 在跳转页面时,使用模板之符串的形式将参数的值拼接到url路径中。该参数的值会在地址栏显示出来,并且放入params对象的属性值中。
- 在接收参数时,使用$router.params对象来获取参数。
- 在动态路由配置时,可以在参数名称后面加上问号,用来防止参数未传递的情况下,程序进入到404页面
- 动态路由也可以通过在要接收参数的页面组件中定义props来接收参数,前提需要在动态路由配置中开启props开关
4 使用keepalive加快页面渲染速度-使用频率不高
将keepalive放在router-view的外层包裹起来,就可以优化页面渲染速度。但是要注意数据被缓存的后果
<!-- 路由出口 -->
<KeepAlive>
<router-view></router-view>
</KeepAlive>
<!-- 利用keepalive 的生命周期处理数据缓存的后果 -->
activated() {
this.$order.getEcomOrderById({id: this.$route.params.id}).then(res => {
console.log("res", res);
this.objOrder = res.data;
})
}
5 导航守卫
功能:拦截所有的路由请求。来决定该路由地址是否放行,并且放行到哪个画面
分类:
- 全局导航:前置守卫beforeEach,解析守卫beforeResolve,后置守卫 afterEach
- 路由独享守卫:beforeEnter
- 组件内守卫: 进入前beforeRouteEnter、更新前beforeRouteUpdate、离开前beforeRouteLeave
//前置守卫
//触发时机:
/*to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子
*/
// 全局前置守卫
router.beforeEach((to, from, next) => {
let isAuthenticated = Vue.prototype.$session.getLoginInfo();
if (to.name !== 'Login' && !isAuthenticated) {
next({ name: 'Login' }) // 前往 login 路由地址,也可以使用 path指定路径
}
else {
next() // 放行,允许通过 next(false)是不允许通过
}
});
//全局解析守卫 参数与 前置守卫一样
//触发时机:同时在所有组件内守卫和异步路由组件被解析之后
router.beforeResolve((to, from, next) => {
// console.log('全局解析守卫');
next();
})
//全局后置守卫 参数没有 next()
router.afterEach((to, from) => {
// console.log('全局后置守卫');
})
//路由独享守卫
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
//组件内守卫
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave
守卫。 - 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫 (2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 调用
beforeRouteEnter
守卫中传给next
的回调函数,创建好的组件实例会作为回调函数的参数传入。