1、定义路由组件(或者从其它文件import 进来)
const Foo = { template: '<div>foodiv>' }
const Bar = { template: '<div>bardiv>' }
2、将组件与path映射
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
3、再将组件与path映射的routes数组传给实例化的vueRouter
const router = new VueRouter({
routes // (缩写) 相当于 routes: routes
})
4、最后将实例化的路由器router 挂载到根实例
const app = new Vue({
router
}).$mount('#app')
5、界面组件里通过this.$router
访问路由器,也可以通过this.$route
访问当前路由
this.$route.params.username
this.$router.go(-1)
this.$router.push('/')
通过**:冒号**,如/:id 进行标记,页面上通过 this.$route.params.id 获取
以下是2种路由参数获取的区别
query | params |
---|---|
/user?id=** | /user/:id |
参数非必填 | 参数必填 |
因路由参数变化时,组件会被复用,所以,组件的生命周期函数不会再被创建,此时可采用以下2种方式,响应参数变化
1、组件watch监听$route 对象
2|、beforeRouteUpdate 导航守卫
因在开发中考虑到路由的美观性、大部分会使用vue路由的history模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。但这种模式在访问未定义的路由时,会报404错误。如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
nginx配置如下:
location / {
try_files $uri $uri/ /index.html;
}
一般处理方式是在路径、组件映射之前 定义通配符 去匹配所有路径*,指定到对应的页面
有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。
声明式 | 编程式 |
---|---|
|
router.push(…) |
|
router.replace(…) |
router.go(n) 类似与 window.history.go(n) 前进|后退多少步。
Vue Router 的导航方法 (push、 replace、 go) 在各类路由模式 (history、 hash 和 abstract) 下表现一致。 借鉴于window.history.pushState、 window.history.replaceState 和 window.history.go等方法。
请移步 vue路由组件传参
参数或查询的改变并不会触发进入/离开的导航守卫
router.beforeEach(function(to,from,next)=>{
next();
// next(false); //中断
// next('/login'); //跳转指定路由
// next(error); //导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
})
router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
不会接受 next 函数也不会改变导航本身
router.afterEach((to, from) => {
markup
// ...
})
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
路由进入前、路由更新前、路由离开后3种组件内守卫
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
== 1. 导航被触发。
2. 在失活的组件里调用离开守卫。
3. 调用全局的 beforeEach 守卫。
4. 在重用的组件里调用beforeRouteUpdate 守卫 (2.2+)。
5. 在路由配置里调用 beforeEnter。
6. 解析异步路由组件。
7. 在被激活的组件里调用 beforeRouteEnter。
8. 调用全局的 beforeResolve 守卫 (2.5+)。
9. 导航被确认。
10. 调用全局的 afterEach 钩子。
11. 触发 DOM 更新。
12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next
的回调函数。==
<transition :name="transitionName">
<router-view>router-view>
transition>
导航完成前获取的数据 通过next() 抛出,这里需要注意的是:beforeRouteEnter 守卫时,页面还没初始化,此时用this是undefined, 可通过next()的方法,指向vue实例
export default {
data () {
return {
post: null,
error: null
}
},
beforeRouteEnter (to, from, next) {
getPost(to.params.id, (err, post) => {
next(vm => vm.setData(err, post))
})
},
// 路由改变前,组件就已经渲染完了
// 逻辑稍稍不同
beforeRouteUpdate (to, from, next) {
this.post = null
getPost(to.params.id, (err, post) => {
this.setData(err, post)
next()
})
},
methods: {
setData (err, post) {
if (err) {
this.error = err.toString()
} else {
this.post = post
}
}
}
}
这个功能只在支持 history.pushState 的浏览器中可用。
scrollBehavior 方法接收 to 和 from 路由对象。第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。
如果返回一个 falsy (不是 false)的值,或者是一个空对象,那么不会发生滚动。
模拟“滚动到锚点”的行为:
scrollBehavior (to, from, savedPosition) {
if (to.hash) {
return {
selector: to.hash
}
}
}
异步滚动:
scrollBehavior (to, from, savedPosition) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ x: 0, y: 0 })
}, 500)
})
}
参考文献 vue-router