{{ post.title }}
{{ post.body }}
官网讲解
简述参考
npm install vue-router --save-dev
2.xvue add vue-router
3.x$router.push({path:'home'});
本质是向history栈中添加一个路由$router.replace({path:'home'});
替换路由,没有历史记录功能包括:
{
// will match everything
//通常用于404客户端
path: '*'
}
{
// will match anything starting with `/user-`
path: '/user-*'
}
单击
相当于调用router.push(...)
params和query
// literal string path
router.push('home')
// object
router.push({ path: 'home' })
// named route
router.push({ name: 'user', params: { userId: '123' } })
// with query, resulting in /register?plan=private
router.push({ path: 'register', query: { plan: 'private' } })
const userId = '123'
router.push({ name: 'user', params: { userId } }) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// This will NOT work
router.push({ path: '/user', params: { userId } }) // -> /user
router.replace(location, onComplete?, onAbort?)
:作用就像router.push,唯一的区别是它导航时没有按下新的历史记录条目,顾名思义 - 它取代了当前的条目。
router.go(n)
:指示在历史堆栈中前进或后退的步数,类似于window.history.go(n)
// go forward by one record, the same as history.forward()
router.go(1)
// go back by one record, the same as history.back()
router.go(-1)
// go forward by 3 records
router.go(3)
// fails silently if there aren't that many records.
router.go(-100)
router.go(100)
//三种重定向的方式
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
})
const router = new VueRouter({
routes: [
{ path: '/a', redirect: to => {
// the function receives the target route as the argument
// return redirect path/location here.
return '/b'
}}
]
})
//别名
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
routes:[
path:'/home/:id',
props:true,
]
export default{
props:['id'],
mounted(){
console.log(this.id)
}
}
mode: 'history',
路由中去掉#号,利用history.pushStateAPI实现URL导航而无需重新加载页面。mode: 'hash',
当路由参数发生变化时,复用组件实例。两种方式:
const User = {
template: '...',
watch: {
'$route' (to, from) {
// react to route changes...
}
}
}
const User = {
template: '...',
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}
}
linkExactActiveClass: 'active-exact',
linkActiveClass: 'active',
You may have noticed that router.push, router.replace and router.go are counterparts of window.history.pushState, window.history.replaceState and window.history.go, and they do imitate the window.history APIs.
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
导航守卫有点类似 中间件,进入 路由 前 先通过守卫,来判断是否可以通过,进而到达页面。
每个守卫功能都有三个参数:
to: Route:导航到的目标Route对象。
from: Route:当前路线被导航离开。
next: Function:必须调用此函数来解析钩子。该操作取决于提供给的参数next:
next():继续前进到管道中的下一个钩子。如果没有留下挂钩,则确认导航。
next(false):中止当前导航。如果浏览器URL已更改(由用户手动或通过后退按钮),则会将其重置为from路径的URL 。
next('/')或next({ path: '/' }):重定向到其他位置。当前导航将中止,并将启动一个新导航。你可以通过任何位置对象next,它允许您指定类似的选项replace: true,name: 'home'在使用任何选项router-link的to道具或router.push
next(error):(2.4.0+)如果传递给的参数next是一个实例Error,导航将被中止,错误将传递给通过注册的回调router.onError()。
确保始终调用该next函数,否则永远不会解析挂钩。
//全局钩子
//使用router.beforeEach注册一个全局 前置守卫
router.beforeEach((to, from, next) => {
// some every 路由元信息
const needLogin = to.matched.some(route => route.meta && route.meta.login);
if (needLogin) {
// 检验
const isLogin = document.cookie.includes('login=true');
if (isLogin) {
next();
return;
}
const toLoginFlag = window.confirm('该页面需要登录后访问,要去登陆吗?');
if (toLoginFlag) {
next('/login');
}
return;
}
next();
})
//使用router.beforeResolve注册一个全局解析守卫
//在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用
router.beforeResolve((to, from, next) => {
console.log('beforeResolve');
next();
})
//router.beforeResolv注册全局后置钩子
//不会接受 next 函数也不会改变导航本身
router.afterEach(() => {
console.log('afterEach');
})
routes:[
{
path:
name:
component:
beforeEnter:(to,from,next)=>{
console.log('路由内的守卫导航')
}
}
]
注意
beforeRouteEnter
是支持给next
传递回调的唯一守卫。对于beforeRouteUpdate
和beforeRouteLeave
来说,this
已经可用了,所以不支持传递回调,因为没有必要了。
beforeRouteEnter(to,from,next){
next(vm=>{
//通过'vm'访问组件实例
})
}
beforeRouteUpdate(to,from,next){
//使用this
this.name = to.params.name
next()
}
// 这个离开守卫通常用来 禁止用户在还未保存修改前突然离开 。该导航可以通过 next(false) 来取消。
beforeRouteLeave(to,from,next){
const answer = window.confirm('leave?save?')
answer?next():next(false)
}
// then, in the parent component,
// watch the `$route` to determine the transition to use
watch: {
'$route' (to, from) {
const toDepth = to.path.split('/').length
const fromDepth = from.path.split('/').length
this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
}
}
Loading...
{{ error }}
{{ post.title }}
{{ post.body }}
export default {
data () {
return {
loading: false,
post: null,
error: null
}
},
created () {
//组件创建后完成获取数据
//此时的data已经被observed
this.fetchData()
},
watch: {
//如果路由有变化,会再次执行该方法
'$route': 'fetchData'
},
methods: {
fetchData () {
this.error = this.post = null
this.loading = true
// replace `getPost` with your data fetching util / API wrapper
getPost(this.$route.params.id, (err, post) => {
this.loading = false
if (err) {
this.error = err.toString()
} else {
this.post = post
}
})
}
}
}
//过这种方式,我们在导航转入新的路由前获取数据。我们可以在接下来的组件的 beforeRouteEnter守卫中获取数据,当数据获取成功后只调用 next 方法。
export default {
data () {
return {
post: null,
error: null
}
},
beforeRouteEnter (to, from, next) {
getPost(to.params.id, (err, post) => {
next(vm => vm.setData(err, post))
})
},
// when route changes and this component is already rendered,
// the logic will be slightly different.
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
}
}
}
}
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return desired position
}
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
scrollBehavior (to, from, savedPosition) {
if (to.hash) {
return {
selector: to.hash
// , offset: { x: 0, y: 10 }
}
}
}
})
//webpack会将具有相同块名称的任何异步模块分组到同一个异步块中。
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')