持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
1. 路由的基本结构
在使用路由的时候,通常通过两个js文件来编写,其中index.js文件用于编写路由的配置信息(重写、守卫等),而routes.js文件则是用于将各个组件注册为路由
还需要在入口main.js文件中进行注册路由
//对上面的router进行引入
import router from '@/router'
new Vue({
render: h => h(App),
//注册路由
router,
}).$mount('#app')
在main.js中注册了路由之后,项目中的所有组件身上将会有$router、$route
属性
$router
一般用于进行路由跳转:push、replace、back、forward、go
$route
一般读取当前路由的一些参数属性:path、name、query、params、meta
2. 路由push和replace的重写
- 如果直接使用Vue自带的push和replace方法,当多次点击同一个路由时,控制台就会报错,虽然不会影响代码的功能实现,但是也需要解决,于是需要对push和replace方法进行重写
//先将VueRouter的push保存一份
let originPush = VueRouter.prototype.push
let originReplace = VueRouter.prototype.replace
//重写push|replace
//第一个参数:告诉原来push方法,往哪里跳转(传递哪些参数)
//第二个参数:成功回调
//第三个参数:失败回调
VueRouter.prototype.push = function (location, resolve, reject) {
if (resolve && reject) {
//call||apply区别
//相同点:都可以调用函数一次,都可以篡改函数上下文一次
//不同点:call与apply传递参数:call传递参数用逗号隔开,apply方法执行,传递数组
originPush.call(this, location, resolve, reject)
} else {
originPush.call(this, location, () => { }, () => { })
}
}
VueRouter.prototype.replace = function (location, resolve, reject) {
if (resolve && reject) {
originReplace.call(this, location, resolve, reject)
} else {
originReplace.call(this, location, () => { }, () => { })
}
}
//配置路由
let router = new VueRouter({
//配置路由
routes,
//滚动行为
scrollBehavior(to, from, savedPosition) {
//返回的这个y=0代表的是滚动条在最上方
return { y: 0 }
}
})
- 重写过后,路由的跳转还是正常使用,没有什么较大的变化
3. 将组件注册为路由
1. 普通方式注册路由
//引入路由组件
import Home from '@/pages/Home'
import Center from '@/pages/Center'
import Msg from '@/pages/Msg'
export default[
{
path:'*',
//默认路由重定向
redirect:'/home'
},
{
path:'/home',
component:Home,
meta: { show: true },
//二级路由
children:[
{
path:'/center',
component:Center
},
]
},
{
path:'/msg',
//在调用$router.push方法时,传入的参数可以是path也可以是name来指定跳转的路由
name:'msg',
component:Msg,
//路由元信息
meta: { show: true }
},
]
- path
指定路由对应的跳转路径,一般都是小写,并且与组件名保持一致
如果是'*'或'/'
即为默认路由地址(第一次访问该网站),一般需要重定向到首页
- name
利用name属性可以给路由命名,在调用$router.push方法或者route-link中跳转时,传入的参数可以是path也可以是name来指定跳转的路由
- component
将组件和路由绑定注册
- children
注册二级路由
- meta
路由元信息,进行路由跳转的时候可以通过meta对象中所带的属性来判断当前路由是否需要进一步处理
- redirect
重定向路由,当跳转到该路由时自动重定向到其他路由(一般用于跳转默认路由)
2. 路由懒加载
- 路由懒加载即当路由被访问时才加载对应的组件,所以在routes.js文件中无需引入组件
export default[
{
path: '*',
redirect: '/home'
},
{
path:'/home',
component:() => import('@/pages/Home'),
meta: { show: true },
children:[
{
path:'/center',
component:() => import('@/pages/Home/Center')
},
]
},
{
path:'/msg',
name:'msg',
component:() => import('@/pages/Msg'),
meta: { show: true }
},
]
4. 路由跳转
- 首先需要在页面结构设置一个路由组件的出口,即路由组件展示的位置
<router-view></router-view>
1. 声明式导航
- 直接通过路由地址跳转
<router-link to="/home">home</router-link>
- 使用对象中带path的方式跳转
<router-link :to="{path:'/home',query:{a:10}}">home</router-link>
- 使用对象中带name的方式跳转
<router-link :to="{name:'home',params:{b:20}}">home</router-link>
采用对象写法还可以携带query或params参数
2. 编程式导航
- 字符串
router.push('/home')
- 使用对象中带path的方式跳转
router.push({
path:"/home",
query:{
a:10
}
})
- 使用对象中带name的方式跳转
router.push({
name:"home",
params:{
b:20
}
});
5. 路由参数
在跳转路由时传递参数,可以在配置对象中添加query
或params
参数属性
路由可以传递参数,那便肯定可以在目标路由对其进行读取
在路由内部如果希望访问到路由携带的参数,可以直接访问$route
对象上的参数属性
$route
上常用的属性包括:path、name、params、query、meta
6. 导航守卫
- 一般用于阻止某个状态的用户前往指定的页面
例如:已登录状态的用户无法前往登录页面
- 守卫分为全局守卫、路由独享守卫和组件内守卫
1. 全局守卫
- 全局守卫有全局前置守卫、全局解析守卫和全局后置守卫
- 最常用的是全局前置守卫,会在路由跳转之前进行判断
router.beforeEach(to,from,next){
//to:可以获取你要跳转到哪个路由的信息
//from:可以获取到你从哪个路由而来的信息
//next:放行函数 next()放行 next(path)放行到指定路由 next(false)
......
}
2. 路由独享守卫
{
path: '/trade',
component: () => import('@/pages/Trade'),
meta: { show: true },
//路由独享守卫
beforeEnter: (to, from, next) => {
//去交易页面,必须是从购物车而来
if (from.path == '/shopcart') {
next()
} else {
//其他的路由组件而来,则停留在当前
next(false)
}
}
},
3. 组件内守卫
<script>
export default{
name:'balabala',
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
</script>