Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
route
指的是当前页面的所有路由信息,
router
是路由的方法。
// 将原本用a标签跳转的功能用router-link实现
// to是指要跳转到的目录,tag是这个点击跳转标签的样式,可以是li的样式等等
router-link-exact-active
: 路由完全匹配,当前选中
router-link-active
: 路由不完全匹配
to
: 表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。
Home
Home
Home
Home
Home
User
Register
除了使用 router-link
标签创建 a
标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
this.$router.push()
:括号里面参数和to的方法一致
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:
const userId = ‘123’
router.push({ name: ‘user’, params: { userId }}) // -> /user/123
router.push({ path: /user/${userId}
}) // -> /user/123
// 这里的 params 不生效
router.push({ path: ‘/user’, params: { userId }}) // -> /user
动态路由:一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到this.$route.params
注意:子路由path不写斜线
import Home from '../views/Home'
import Products from '../views/Products'
import Category from '../views/Category'
export default [
{
path: '/home',
name: 'home',
component: Home
}, {
path: '/Products',
name: 'products',
component: Products,
children: [{
path: ':cateName',//子路由path不写斜线
name: 'category',
component: Category
}]
}
]
子路由(children)的router-view
要在父组件里面去配置
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar
(侧导航) 和 main
(主内容) 两个视图。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view
没有设置名字,那么默认为 default
头部
export default [
{
path: '/home',
name: 'home',
components: {//这里一定要写components,default指的是没有没有命名的那个组件(在这里是app.vue)
default: Home,
'x-footer': Footer
}
}
常规参数只会匹配被 / 分隔的 URL 片段中的字符。如果想匹配任意路径,我们可以使用通配符 (*):
{
// 会匹配所有路径
path: '*'
}
{
// 会匹配以 `/user-` 开头的任意路径
path: '/user-*'
}
注意:含有通配符的路由应该放在最后
export default [
{//从"/"重定向到"/home",这样根路径就变成了home
path: '/',
redirect: '/home'
}
]
vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航
全局导航守卫可以在main.js里做,因为需要在router的实例上做,用来做全局的权限验证
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
next()
})
to
: 要到哪个组件去,
from
: 从哪个组件来的
next
: 必须要调用next( )这个方法否则路由无法跳转访问
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建,在created之前就会执行这个守卫
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
beforeRouteUpdate
: 路由更新之前,这里可以发送ajax请求。在使用beforeRouteUpdate时一般会先使用beforeRouteEnter。
在beforeRouteEnter
中不能获取this,可以在next里传一个回调函数,该回调函数的第一个形参VM就是this,且beforeRouteEnter只会在第一次进来时执行一次。
在之前没有beforeRouteUpdate
,使用watch
来替代 ,watch可以watch this.上的所有东西
把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,利用import返回promise来异步加载
const Foo = () => import('./Foo.vue')
把组件按组分块,下面的注释意思是:将这三个组件的代码打包到一个js文件里。
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
native
在加不上事件的时候使用,往当前组件的的根dom元素上绑定一个事件