1. 下载安装vue-router
安装 | Vue Router (vuejs.org)
直接通过Unpkg.com 下载或者引入CDN。
npm install vue-router@4
// 或者
yarn add vue-router@4
2. vue-router 基本配置
使用 router-link 组件进行导航,通过传递 to
来指定链接,<router-link>
将呈现一个带有正确 href
属性的 <a>
标签,路由匹配到的组件将渲染在 <router-view></router-view>
。
// 第一步定义路由与组件之间的映射关系
let routes = [
{
path: '/',
component: {
template: `
<div>
<h1>首页</h1>
</div>
`,
}
},
{
path: '/about',
component: {
template: `
<div>
<h1>关于我们</h1>
</div>
`,
}
},
];
// 第二步 创建 router对象 把上一步的配置传参进去
let router = new VueRouter({
routes: routes
})
// 第三步 把 router 对象放到 vue 实例中去
new Vue({
el: '#app',
router: router
})
// 第四步 使用 router-link 与 router-view 标签
<div id="app">
<div>
<router-link to="/">首页</router-link>
<router-link to="/about">关于我们</router-link>
</div>
<div>
<router-view></router-view>
</div>
</div>
// router-link 相当于a标签, router-view 是显示页面的容器
这样一来,点击链接就会显示对应的组件,并且地址栏会发生变化。
3. 传参以及获取传参
我们可以在路径中使用一个动态字段来获取参数,我们称之为路径参数。
第一种传参方式:
地址栏为:/user/foo
先在rouer-link 中传参
<!-- 先在rouer-link 中传参 -->
<router-link to="/user/foo">foo</router-link>
然后在router配置里面接收参数
{
path: '/user/:name', // :name 表示参数名
component: {
template: `
<div>
<h1>我叫:{{$route.params.name}}</h1>
</div>
`,
} // $route.params.name 接收参数
}
第二种传参方式:
地址栏为:/user/foo?age=18
{
path: '/about',
component: {
template: `
<div>
<h1>关于我们</h1>
<h1>我们:{{$route.query.age}}岁了</h1>
</div>
`,
}
}
// $route.query.age 接收参数 无需在router-link中传参 只需在 地址栏传参 ?age=18 这种格式
// 多个参数使用 & 分割
4. 子路由
通过 Vue Router 可以使用嵌套路由配置来视线嵌套组件结构。
比如在某个路由下想要再显示一层路由,只需要在 对应的路由配置中增加 children
选项,跟第一层路由一样,别忘了在父级路由上面添加 router-link
与 router-view
标签。
{
path: '/user/:name',
component: {
template: `
<div>
<h1>我叫:{{$route.params.name}}</h1>
<router-link :to="'/user/'+ $route.params.name + '/more'">更多信息</router-link>
<router-view></router-view>
</div>
`
},
children: [
{
path: 'more',
component: {
template: `
<div>
用户{{$route.params.name}}的详细信息
</div>
`
}
}
]
}
5. 手动访问和传参
除了使用 <router-link>
创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过 router.push(...)
来实现。现在来添加一个按钮:
<router-link to="/">首页</router-link>
<router-link to="/about">关于我们</router-link>
<router-link to="/user/foo">foo</router-link>
<button @click="surf">点击跳转</button>
new Vue({
el: '#app',
router: router,
methods: {
surf: () => {
setTimeout(() => {
router.push('/about') // 使用push方法
}, 2000)
}
}
})
两秒后跳转到 about 组件,动态地跳转传参:
{
path: '/user/:name',
name: 'user', // 当前路由的名字
component: {
template: `
<div>
<h1>我叫:{{$route.params.name}}</h1>
<router-link :to="'/user/'+ $route.params.name + '/more'">更多信息</router-link>
<router-view></router-view>
</div>
`
},
children: [
{
path: 'more',
component: {
template: `
<div>
用户{{$route.params.name}}的详细信息
</div>
`
}
}
]
}
点击按钮执行的函数:
surf: () => {
setTimeout(() => {
router.push('/about')
setTimeout(() => {
router.push({ // 这里传入一个对象 name 为当前路由的名字
name: 'user', params: {
name: 'foo'
}
})
}, 2000)
}, 2000)
}
6. 命名视图
使用多个 router-view ,一个路由对应多个路由 视图 即一个 router-link 对应 多个 router-view
<div>
<router-link to="/">首页</router-link>
<router-link to="/about">关于我们</router-link>
<router-link to="/user/foo">foo</router-link>
<button @click="surf">点击跳转</button>
</div>
<div>
<router-view name="sidebar"></router-view>
<router-view name="content"></router-view><!-- 首先取名 -->
</div>
{
path: '/about',
components: { // 这里是components
sidebar:{ // 对象的键名就是router-view的name值
template:`
<div>用户的页面一</div>
`
},
content:{
template:`
<div>用户的页面二</div>
`
},
}
},
7. 导航钩子
其实就是路由的生命周期函数,在期间可以做一些验证,判断是否跳转,实现路由守卫的效果。正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
什么是路由守卫?
简单理解为就是你在点击链接进路由之前,首先把你拦住进行检查,当然可以做的不止是检查验证,还可以用其他的钩子函数进行一些别的操作。
vue-router一共给我们提供了三大类钩子函数来实现路由守卫:
- 全局钩子函数(beforeEach、afterEach)
- 路由独享的钩子函数(beforeEnter)
- 组件内钩子函数(beforeRouterEnter、beforeRouterUpdate、beforeRouterLeave)
这里只讲一下全局函数:
router.beforeEach(async (to, from) => {
if (
// 检查用户是否已登录
!isAuthenticated &&
// ❗️ 避免无限重定向
to.name !== 'Login'
) {
// 将用户重定向到登录页面
return { name: 'Login' }
}
})
可选的第三个参数 next ,表示向任何导航守卫传递第三个参数。
router.beforeEach((to, from, next) => {
// to:即将要进入的路由
// from:当前导航正要离开的理由
// next:跳转到下一个路由
if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
else next()
})
8. 理由匹配与元数据
路由匹配:用于对当前路由地址的匹配与验证。
这里可以循环matched这个数组,看每一项的 path 有没有等于’/goodsList’
,只要其中一个有,那么就让它跳转到登录状态。
router.beforeEach((to, from, next) => {
if (to.matched.some(function (item) {
return item.path === '/booklist'
})) {
next('/login')
} else
next()
})
只是通过 path 还不足以满足所有场景,比如除了登录,还有资讯列表、广告列表,就开始捉襟见肘。那么,我们可以再每个路由上添加 meta 属性来进行指定路由的验证更加方便。
元数据:在路由配置项里面添加的数据标志 meta
属性,以便用于验证检验是否跳转等功能。
{
path: '/about',
meta:{ // 元数据
login_in:false
},
components: {
sidebar:{
template:`
<div>用户的页面一</div>
`
},
content:{
template:`
<div>用户的页面二</div>
`
},
}
},
在逻辑中使用
// 全局的 导航钩子函数
router.beforeEach((to, from, next) => {
if (to.matched.some(function (item) {
return item.meta.login_in
})) {
next('/login')
} else
next()
})
网友评论