前端路由主要有两种实现方法:Hash 路由 和 History 路由
url 的 hash
是以 #
开头,原本是用来作为锚点,从而定位到页面的特定区域。当 hash
改变时,页面不会因此刷新,浏览器也不会向服务器发送请求。
http://www.xxx.com/#/home
hash
改变时,并会触发相应的 hashchange
事件。当 hash 路由发生了跳转,便会触发 hashchange 回调,回调里可以实现页面更新的操作,从而达到跳转页面的效果。
window.addEventListener('hashchange', function () {
console.log('render');
});
HTML5 规范中提供了 history.pushState
和 history.replaceState
来进行路由控制。通过这两个方法,可以实现改变 url 且不向服务器发送请求。路径当中没有了#,更加美观。但是 History 路由需要服务器的支持,并且需将所有的路由重定向到根页面。
改变 url:1.调用 history.pushState 或 history.replaceState;2.点击浏览器的前进与后退。
1. 定义 (路由) 组件。可以从其他文件 import 进来
const Foo = { template: 'foo' }
const Bar = { template: 'bar' }
2. 定义路由 。每个路由应该映射一个组件。 其中"component" 可以是通过 Vue.extend() 创建的组件构造器,或者,只是一个组件配置对象。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
3. 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
routes // (缩写) 相当于 routes: routes
})
4. 创建和挂载根实例。
const app = new Vue({
router
}).$mount('#app')
5.使用
aaaa
routes:路由规则配置
mode:模式配置。hash模式,history模式。
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 中
path: 'profile',
component: UserProfile
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 会被渲染在 User 的 中
path: 'posts',
component: UserPosts
}
]
}
]
})
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})
一个“路径参数”使用冒号 :
标记。当匹配到一个路由时,参数值会被设置到 this.$route.params
,可以在每个组件内使用。这时候增加了一个$route的属性。
$route.params
获取的是路由配置规则中匹配到的路由信息,通常称之为路由参数
this.$route.params.xxx
来拿到匹配的路由值
1、router.push(location, onComplete?, onAbort?)
在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push
2、router.replace(location, onComplete?, onAbort?)
跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
3、router.go(n)
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
})
当用户访问 /a
时,URL 将会被替换成 /b
,然后匹配路由为 /b
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
/a
的别名是 /b
,意味着,当用户访问 /b
时,URL 会保持为 /b
,但是路由匹配则为 /a
,就像用户访问 /a
一样。
//全局前置守卫
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
//to: Route: 即将要进入的目标 路由对象
//from: Route: 当前导航正要离开的路由
//next: Function: 一定要调用该方法来 resolve 这个钩子
//next(): 进行管道中的下一个钩子。
//next(false): 中断当前的导航。
//next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。
})
//全局后置钩子
router.afterEach((to, from) => {
//这些钩子不会接受 next 函数也不会改变导航本身
})
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
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 守卫 。
5.在路由配置里调用 beforeEnter。
6.解析异步路由组件。
7.在被激活的组件里调用 beforeRouteEnter。
8.调用全局的 beforeResolve 守卫 。
9.导航被确认。
10.调用全局的 afterEach 钩子。
11.触发 DOM 更新。
12.用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数