vue-router是vue的路由管理插件,使用了很长时间vue,今天把vue-router的官网教程从头到尾复习了一遍,回头对照之前做的项目发现很多问题都可以通过路由去解决,同时也发现任何一样东西细研究起来内容都不少,以下记录一下复习心得
vue2.0创建的vue项目,目录结构如下
使用方法
1、安装方法:yarn add vue-router
2、配置路由
import page01 from '../pages/page01.vue'
import page02 from '../pages/page02.vue'
import page03 from '../pages/page03.vue'
import page04 from '../pages/page04.vue'
import page06 from '../pages/page06.vue'
const routes = [{
path: '/page01',
component: page01,
children:[{//子路由
path:"aaa",
component:page03
},{
path:"bbb",
component:page04
}],
alias:'/p' //别名
},{
path: '/page02/:id', //参数id
name:"page02", //命名路由
component: page02
},{
path: '/',
redirect: '/login' //重定向到登录页
},{
path: '*',
component: page06 //404页面
}]
export default routes
3、在main.js中使用vue-router,需要注意的是一定要调用Vue.use(VueRouter)
,如果没调用这个方法,那么在组件当中就无法使用
和
组件
import VueRouter from 'vue-router'
import routes from './router/routes'
// 路由
Vue.use(VueRouter)
const router = new VueRouter({
routes
})
new Vue({
router,
render: h => h(App),
}).$mount('#app')
4、在组件中使用vue-router
通过以上配置路由的功能就算是实现了,
的内容会根据配置好的routes进行匹配
routes的配置
路由的配置我主要记录几点:命名路由、路由传参、嵌套路由、路由别名、路由重定向、路由正则匹配
1、命名路由
命名路由就是在配置路由的时候可以添加name属性给该路由起个名字,主要作用是跳转页面的时候就可以使用该名称进行跳转
const routes = [{
path: '/page02',
name:"page02", //命名路由
component: page02
}]
调用方法this.$router.push({name:"page02"})
或者this.$router.push({path:"/page02"})
都可以实现跳转。
2、路由传参
首先看一下传参对象的内容
路由传参就是在跳转路由的时候可以向目标路由传递参数,配置方式通过/page02/:id
的方式向page02页面传递id参数
const routes = [{
path: '/page02/:id', //参数id
name:"page02",
component: page02
}]
传递方式有两种,一种是通过path的方式传递,一种是通过params属性的方式传递
const userId = 123
this.$router.push({path:`/page02/${userId}`}) //path的方式跳转路由
this.$router.push({name:"page02",params:{id:userId}}) //命名路由的方式跳转路由
需要注意的是通过path的方式传递参数时params属性会被忽略掉,无论params中传递什么参数都无法传递到目标路由中
this.$router.push({path:`/page02/${userId}`,params:{userName:"aaa"})
通过以上方式传递参数的时候page02页面只能获取到userId,而userName是获取不到的,所以想要传递路由中配置的参数以外的数据需要使用命名路由的方式跳转,或者使用query的方式
this.$router.push({path:`/page02/${userId}`,query:{userName:"aaa"})
query会被添加到路由的query属性中,获取的时候通过this.$route.query.userName
注意:路由传参主要注意path方式和name方式的区别,以及params和query的使用方式
3、嵌套路由
嵌套路由就是子路由,路由中的每个页面中又可以添加
标签,该标签会匹配二级路由对应的模板。
const routes = [{
path: '/page01',
component: page01,
children:[{//子路由
path:"aaa",
component:page03
},{
path:"bbb",
component:page04
}]
}]
例如方面的路由配置,page01模板中的
标签就有两种形态,该组件在http://localhost:8080/#/page01/aaa
路由下回匹配到page03,但是需要注意的是如果http://localhost:8080/#/page01/
就匹配不到任何路由,可以添加一个配置去避免
const routes = [{
path: '/page01',
component: page01,
children:[{//子路由
path:"aaa",
component:page03
},{
path:"bbb",
component:page04
},{
path:"/",
component:page05
}]
}]
4、路由别名
之前没有了解过,在实际开发中也没有用过,他的把主要作用我觉得就是可以通过多个名字去匹配一个路由
cosnt routes = [{
path: '/a',
component: A,
alias: '/b'
}]
按照上面的配置http://localhost:8080/#/a
和http://localhost:8080/#/b
两个路由匹配的UI是相同的,都是组件A
5、路由重定向
路由重定向字面意思就很清楚了,就是重新定向
const routes = [{
path:"/page01",
redirect:"/login"
}]
当跳转到http://localhost:8080/#/page01
的时候路由会直接跳转到http://localhost:8080/#/login
,注意是直接跳到login而不是跳到page01之后再跳到login,而且传参的时候只能传递query,params无法传递,但是redirect有三种形式,字符串,路有对象和回调函数
const routes = [{
path:"/page01",
redirect:"/login"
}]
const routes = [{
path:"/page01",
redirect:{name:""}
}]
const routes = [{
path:"/page01",
redirect:{path:""}
}]
const routes = [{
path:"/page01",
redirect:to=>{
console.log(to) //返回page01页面的$route数据
return "/page02"
}
}]
所以,传参的时候具体使用哪种方式定义redirect就要看情况,如果有params需要传递就用回调函数的形式,如果直传query则使用字符串的方式就可以
6、路由正则匹配
目前我想到的能用到路由正则匹配的地方就是404匹配
const routes = [{
path: '*',
component: page06 //404页面
}]
编程式导航
vue-router的路由跳转不仅仅依靠router-link标签的方式,编程式导航就是使用$router的方法进行路由跳转,看一下$router对象的内容
我主要使用的路由跳转方法是push、replace、back
push:通过
this.$router.push('/page01')
方法调用,在history中会加入一条url
replace:通过
this.$router.replace('/page01')
方法调用,在history中不会新加url,但会替换掉当前url
back:通过
this.$router.back()
方法调用,返回上一个history记录
push和replace方法接收一个参数,可以使字符串、路有对象,路有对象可以使path方式也可以是name方式,上面已经提到过,但是在强调一遍,path方式的路有对象,params会被忽略
const userId = '123'
router.push({ name: 'user', params: { userId }})
router.push({ path: `/user/${userId}` })
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }})
另外,需要注意的是path中的/
是根路径的意思,例如我们现在在page02的路由页面,在该路由下调用router.push('/page03')
和router.push('page03')
的效果是不一样的,前者会跳转到http://localhost:8080/#/page03
后者会跳转到http://localhost:8080/#/page02/page03
路由监听
路由监听的方式是在组件的watch属性中监听$route
,当页面中this的$route发生变化时会执行相应回调
之所以需要路由监听是因为在同一个路由下参数发生变化时组件的生命周期钩子不会执行,例如从 /page02/id123 导航到 /page02/id456,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。所以路由发生变化的时候需要做哪些事情需要单独处理,当然也可以用路由守卫去做,上面的监听函数和路由守卫钩子函数都会执行,且返回的参数相同
路由守卫
vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
全局:全局钩子分前置和后置,区别是前置是跳转前守卫,后置是跳转后守卫
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// 需要调用next(),方法才能跳转成功
})
router.afterEach((to, from) => {
// 因为是跳转之后的钩子所以没有next方法
})
例如在项目中有些路由是只有用户登录才能访问的那么就可以在全局进行判断
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!auth.loggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next() // 确保一定要调用 next()
}
})
matched是跳转路由时所有匹配的路由集合,如果是跟路由matched就会是当前匹配的路由,如果是嵌套路由的子路由,matched就是当前路由和父级路由的集合,meta是配置routes是给路由添加的数据,可以在matched中的路由单元获取到
单个路由独享:
const routes: [{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
}
}]
组件内的守卫:
我只使用过全局守卫,大屏项目切换页面的时候修改vuex中的title数据
路由过渡
路由过渡是
API
VueRouter配置
const router = new VueRouter({
mode:"hash", //路由模式
linkActiveClass:"active", //选中class名
routes
})
除了以上的知识点之外,路由还有很多内容,以上是我在开发中我觉得有用的我整理出来了,如果向全面了解vue-router,还是建议看官方文档,然后多测试多写多练。