路由Router
路由注意点
- 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹
- 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
- 第个组件都有自己的$route属性,里面存储着自己的路由信息。
- 整个应用只有一个router,可以通过组件的$router属性获取到
路由使用
//脚手架main.js引入
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
//A.导入js文件
<script src="lib/vue_2.5.22.js"></script>
<script src="lib/vue-router_3.0.2.js"></script>
/*B.添加路由链接:<router-link>是路由中提供的标签,默认会被渲染为a标签,to属性默认被渲染为href属性,
to属性的值会被渲染为#开头的hash地址*/
<router-link to="/login">Login</router-link>
<router-link class="" active-class="" to="">router跳转标签</router-link>
//C.添加路由填充位(路由占位符)
<router-view></router-view>
//D.定义路由组件
var User = { template:"<div>This is User</div>" }
//脚手架定义组件
<template></template>
<script></script>
<style lang="less" scoped></style>
//引入组件
const Rights = () => import('../pages/power/Rights.vue')
路由守卫
//E.配置路由规则并创建路由实例
//路由守卫定义路由必须使用变量接收,不能直接暴露
var myRouter = new VueRouter({
//routes是路由规则数组
routes:[
//每一个路由规则都是一个对象,对象中至少包含path和component两个属性
//path表示 路由匹配的hash地址,component表示路由规则对应要展示的组件对象
{path:"/user",component:User},
//在路由元信息meta,里面设置路由是否需要守卫 ,需要权限的校验
{name:'cong',path:"/login",component:Login,meta:{isAuth:true}},
//重定向
{path: '/',redirect: '/login',},
//子路由
{
path:'/home',component:Home,
children:[
{path:'welcome',component:Welcome},
{path:'welcome2',component:Welcome2}
]
}
],
// 去掉url中的#
mode:'history',
//设计路由跳转后界面的滚动条定位
scrollBehavior:()=>({x:0,y:0})
});
//挂载路由导航守卫
//初始化的时候调用、在每一次路由切换之前调用
//全局前置路由守卫
myRouter.beforeEach((to, from, next) => {
// to将要访问的路径,目的地
// to.path、to.name、to.meta
// to 也可以 to.name ,自己console.log 看可以用的参数
// from从哪个路径跳转而来,来自
// next是一个函数,表示放行
// next() 放行 next("/login")强制跳转
if (to.path === "/login") {
return next();
}
if (to.path ==='home/new' || to.path === '/home/message'){
next();
}
//如果判断的路由过多,则使用路由元信息.判断是否要拦截,要拦截就验证token
if (to.meta.isAuth){
// 获取token
const tokenStr = window.sessionStorage.getItem('token');
// 如果存在token则放行
if (!tokenStr) {
return next('/login');
} else {
// if(to.path === "/home"){return next();}
next();
}
}
//不用的写法,后置守卫直接实现
if(to.meta.isAuth){ //需要守卫
if(localStorage.getItem('school') === '丛'){
//可以切换标题名称 ,变量没有值 显示首页
document.title = to.meta.title || "首页"; //放在放行之前
next();
}else{
alert('学校名不对,无权限')
}
}else{
//可以切换标题名称 ,变量没有值 显示首页
document.title = to.meta.title || "首页"; //放在放行之前
next()
}
});
//全局后置路由守卫,没有next!用的不多
//在路由里面设置元信息
{path:'/about',compontent:About,meta:{title:'关于'}}
myRouter.afterEach((to, from) => {
console.log('后置路由守卫',to,from);
if(to.meta.title){
//可以切换标题名称 ,变量没有值 显示首页
document.title = to.meta.title || "首页"; //放在放行之前
}else{
document.title = "默认标题"
}
}
//独享守卫只有前置守卫,没有后置守卫
{
name:'home',
path:'index',
componet:Home,
beforeEnter:(to,from,next) =>{
//守卫
}
}
//组件内路由守卫
export default{
//通过路由规则,进入该组件时被调用
beforeRouteEnter(to,from,next){
next()
},
//通过路由规则,离开该组件时被调用
beforeRouteLeave(to,from,next){
next()
}
}
export default myRouter
//F.将路由挂载到Vue实例中
new Vue({
el:"#app",
//通过router属性挂载路由对象
router:myRouter
})
//脚手架项目单文件router.js
export default myRouter
//脚手架引入vue、vue-router
import Vue from 'vue'
import Router from 'vue-router'
//路由懒加载
const Login = () => import('../pages/Login.vue')
const Home = () => import('../pages/Home.vue')
const Welcome = () => import('../pages/Welcome.vue')
const Port = () => import('../pages/Port.vue')
const Rights = () => import('../pages/power/Rights.vue')
//动态路由匹配(★★★)
var User = { template:"<div>用户:{{$route.params.id}}</div>"}
var myRouter = new VueRouter({
//routes是路由规则数组
routes: [
//通过/:参数名 的形式传递参数
{ path: "/user/:id", component: User },
]
})
//如果使用$route.params.id来获取路径传参的数据不够灵活。
//1.我们可以通过props来接收参数
var User = {
props:["id"],
template:"<div>用户:{{id}}</div>"
}
var myRouter = new VueRouter({
//routes是路由规则数组
routes: [
//通过/:参数名 的形式传递参数
//如果props设置为true,route.params将会被设置为组件属性
{ path: "/user/:id", component: User,props:true },
]
})
//2.还有一种情况,我们可以将props设置为对象,那么就直接将对象的数据传递给组件进行使用
var User = {
props:["username","pwd"],
template:"<div>用户:{{username}}---{{pwd}}</div>"
}
var myRouter = new VueRouter({
//routes是路由规则数组
routes: [
//通过/:参数名 的形式传递参数
//如果props设置为对象,则传递的是对象中的数据给组件
{ path: "/user/:id", component: User,props:{username:"jack",pwd:123} },
]
})
//3.如果想要获取传递的参数值还想要获取传递的对象数据,那么props应该设置为函数形式。
var User = {
props:["username","pwd","id"],
template:"<div>用户:{{id}} -> {{username}}---{{pwd}}</div>"
}
var myRouter = new VueRouter({
//routes是路由规则数组
routes: [
//通过/:参数名 的形式传递参数
//如果props设置为函数,则通过函数的第一个参数获取路由对象
//并可以通过路由对象的params属性获取传递的参数
//
{ path: "/user/:id", component: User,props:(route) => {
return {username:"jack",pwd:123,id:route.params.id}
}
},
]
});
//路由添加别名
var myRouter = new VueRouter({
//routes是路由规则数组
routes: [
//通过name属性为路由添加一个别名
{ path: "/user/:id", component: User, name:"user"},
]
})
//添加了别名之后,可以使用别名进行跳转
<router-link to="/user">User</router-link>
<router-link :to="{ name:'user' , params: {id:123} }">User</router-link>
//replace 属性设置路由不能返回
//1.控制路由跳转时操作浏览器历史记录的模式
//2.浏览的历史记录有两种定入方式:分别为push和replace,push是追加历史记录,replace是替换当前记录。路由跳转时默认为push
<router-link replace to="/user">cong</router-link>
//还可以编程式导航
myRouter.push( { name:'user' , params: {id:123} } )
//编程式导航(★★★)
//页面导航的两种方式:
//A.声明式导航:通过点击链接的方式实现的导航
//B.编程式导航:调用js的api方法实现导航
//Vue-Router中常见的导航方式:
this.$router.push("hash地址");
this.$router.push("/login");
this.$router.push({ name:'user' , params: {id:123} });
this.$router.push({ path:"/login" });
this.$router.push({ path:"/login",query:{username:"jack"} });
this.$router.go( n );//n为数字,参考history.go
this.$router.go( -1 );
//添加一个/userinfo的路由规则
{ path:"/userinfo/:id",component:UserInfo,props:true},
goDetail(id){
this.$router.push("/userinfo/"+id);
}