一个早上被组件与页面组件之间跳晕了,快让我写篇blog静静,屡屡思路。
目录
一.路由传参
1.路由配置
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头,相当于在path里声明了一个变量 id为变量名
{
path: '/user/:id',
component: User
}
]
})
2.跳转(重点来咯)
//匹配上 '/user/:id' 路径,01001的值会赋给id
<router-link to="/user/01001">用户01001的信息</router-link>
3.组件中获取id的值
//模板里的写法:(在vue对象中的data函数中使用时,不需要this)
$route.params.id
//脚本里的写法:(就是vue对象中使用时,需要用this)
this.$route.params.id
$router与$route的区别:
$router:表示vueRouter对象,即就是router文件夹下index.js中所有的路由配置。因为我们在vue对象里将vueRouter对象(router)植入到根属性里了,所以在每个组件内部都可以利用$router拿到该对象。
$route:表示匹配到当前的路由对象,也就是router文件夹下index.js中复合当前路由对象的一条路由配置。
总结:路由传参
1.分类:
- params
传:
1)动态路由匹配(路由配置)
{
name:"user",
path: '/user/:id', //id:相当于声明了变量
component: User
}
2)跳转时传参
1)、跳转时,使用字符串
//声明式
<router-link to="/user/01001">用户01001的信息</router-link>
//编程式
this.$router.push("/user/01001");
2)、跳转时,使用对象
//声明式: 命名的路由,同时传参
<router-link :to="{ name: 'user', params: { id: '01001' }}">User</router-link>
//编程式:
this.$router.push({ name: 'user', params: { id: '01001' }})
接:
//模板里的写法:
$route.params.参数名
//脚本里的写法:
this.$route.params.参数名
- query
传:
1)路由配置不用改(无需使用动态路由配置)
{
path: '/user',
component: User
}
2)跳转时使用path
//跳转时,使用字符串
//声明式:
<router-link to="/Reg?userid=007&username=mjl">User</router-link>
//编程式:
this.$router.push("/Reg?userid=007&username=mjl");
//跳转时,使用对象:
//声明式:
<router-link :to="{ path: '/user', query: { id: '01001' }}">User</router-link>
//编程式:
$router.push({ path: '/user', query: { id: '01001' }})
//注意:如果提供了 path,那么params 会被忽略
// 带查询参数,变成 /user?id=01001
温馨提醒:
name对应params;path对应query。
接:
//模板里的写法:
$route.query.参数名
//脚本里的写法:
this.$route.query.参数名
使用创景区别:
- query:传递多个参数时,query方式对应的地址栏上便于阅读。
- params:传递一个参数。
二.路由传参和props
一个组件在项目中,有两种使用方式(组件显示在浏览器上):
- 自定义标签的方式,外部给组件传数据,用props;
- 使用路由跳转的方式,外部给组件传数据,用params/query。
如果在一个组件需要从外部传入数据,并且项目中以上两种方式都会出现,那么问题来了,组建内部如何适应这两种情况,如何使用props属性将组件和路由解耦?
在路由配置中,将props被设置为true,route.params将会被设置为组件属性。
路由配置:
{
path: '/user/:id',
component: User, props: true
}
组件:
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
在组件的script中,书写props属性。
三.捕获所有路由/404 Not Found路由
1.通配符
'*' //会匹配所有路径
'/user-*' //匹配以 user-开头的任意路径 /表示根路径
注:
- 路由匹配的顺序是按照路由的配置顺序进行的,所以需要将含有通配符(*)的路径放在最后面。
- 当使用通配符时,$route.params内会自动添加一个名为pathMatch参数,它包含了URL通过通配符被匹配的部分。
eg:配置一条以user-开头的任意路径。通过路由跳转和组件观察刚才提到的注意事项。
路由配置:
{
// 会匹配以 `/user-` 开头的任意路径
path: '/user-*'
}
路由跳转:
this.$router.push('/user-admin')
组件中:
this.$route.params.pathMatch // admin就是刚才匹配到的url的部分
eg:404页面——当用户输入的地址或者因操作不当,引起地址发生变化时,为了提高用户的友好性,我们需要设置一个404页面,委婉的提醒用户。
//当路径不能匹配到上述路径时,跳转到Nopage组件(404页面)
{
path: '*',
component: NoPage组件
}
四.命名路由
就是给路由起个名字。嘻嘻~是不是很通俗易懂呢。话不多说,上代码
1.路由配置
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user', //路由的名字
component: User
}
]
})
2.跳转
//使用对象的形式传参,就需要v-bind
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
五.重定向(redirect)
{
path: '/', //默认页
redirect: '/home' //配置型跳转,会重定向到path为/home的这条路由配置。显示Home这个组件
},
{
path: '/home',
component: 'Home'
}
六.嵌套路由
1.子嵌套路由
1)路由配置
// src/router/index.js
const router = new VueRouter({
routes: [
{
path: '/user/:id',
component: User,
children: [
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 <router-view> 中
path: 'profile',
component: UserProfile //子组件UserProfile显示在父组件User里的<router-view>
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 会被渲染在 User 的 <router-view> 中
path: 'posts',
component: UserPosts//子组件UserPosts显示在父组件User里的<router-view>
}
]
}
]
})
2)组件的展示
子组件会展示在父组件中的<router-view> 的位置。
七.路由模式
1.分类:hash和history
2.区别:
- 外观上:
hash模式时,路径上有#;
history模式时,路径上没有#。
- 与后端的区别
hash模式不会给后端发送请求(背后利用锚点实现);
history模式会给后端发送请求,需要后端配合。会在服务端增加一个覆盖所有情况的候选资源:如果URL匹配不到任何静态资源,则应该返回同一个index.html页面,这个就是app依赖的页面。否则,就会返回404.如果厚度那有同名的url,那么会找后端的url。
// src/router/index.js
let router = new VueRouter({ //插件路由对象
routes,
// mode:'hash'//哈希模式 location.href
mode:'history'//历史记录 history.pushState
});
八.路由守卫
1.分类:全局守卫和路由独享守卫
- 全局守卫
// src/router/index.js
//前置钩子
router.beforeEach((to, from, next) => {
// to: 目标路由
// from: 当前路由
// next() 跳转 一定要调用
next(false);//不让走
next(true);//继续前行
next('/login')//走哪
next({path:'/detail/2',params:{},query:{}})//带点货
// 守卫业务
if(to.path=='/login' || to.path=='/reg' ){
next(true)
}else{
//是否登录的判断
if(没有登录过){
next('/login');
}else{
next(true);
}
}
})
//后置
router.afterEach((to,from)=>{
//全局后置守卫业务
})
路由执行过程:
1、请求一个路径:如:/Index
2、经历前置守卫(路由配置前),决定了能去哪个路径
3、根据去的路径,找对应component(路由配置)
4、经过后置守卫(路由配置后)
5、创建组件
- 路由独享守卫(只有前置)
// src/router/index.js
{
path: '/user',
component: User,
//路由独享守卫
beforeEnter: (to,from,next)=>{ //路由独享守卫 前置
console.log('路由独享守卫');
if(Math.random()<.5){
next()
}else{
next('/login')
}
}
}
九.组件内部守卫
//在组件内部写:
//组件内部钩子
beforeRouteEnter (to, from, next) {//前置
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {//后置
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
路由独享守卫与组件内部守卫的区别:
路由独享守卫,守的是path;
组件内部守卫,守的是component。
绕啊绕,blue胖胖终于绕出来了。但还是晕晕哒~