vue-router
1,路由安装
1,安装指令:
npm install vue-router
2,项目中 main.js 引入
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
2,route 与 router 的区别
- route:通过$route来获取路由传参的数据
- router:是VueRouter的一个实例对象,是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性;可以通过他来进行路由切换
3,动态路由匹配
1,同一个组件,对应不同的id时,都是使用这个组件进行渲染,可以在路由中进行匹配
const User = { template: '<div>User</div>' }
const router = new VueRouter({
routes: [ // 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]})
2,一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params 进行接收
3,当导航从一个详情页到另一个详情页时候(用的同一个组件时候),组件会被复用,意味着组件的生命周期钩子不会再被调用,所以我们在组件中加一个watch,观察路由
const User = {
template: '...',
watch: {
$route(to, from) {
// 对路由变化作出响应...
}
}}
或者使用 2.2 中引入的 beforeRouteUpdate 导航守卫:
const User = {
template: '...',
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}}
4,捕获所有路由或 404 Not found 路由
{ // 会匹配所有路径
path: '*'
}
{ // 会匹配以 `/user-` 开头的任意路径
path: '/user-*'
}
5,嵌套路由
1,借助 vue-router,使用嵌套路由配置,就要在页面中加上 <router-view></router-view>
注:
- 如果想在该页面中跳转页面,那就直接作为当前页面的子路由 children;
- 如果想在另一个整页面中跳转,就直接写在route根目录下
2,要在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置:
{
path: '/route',
name:'route',
component: () => import( './../components/route.vue'),
children:[
{
path: '/route/routeOne/:name',
name:'routeOne',
component: () => import( './../components/routeOne.vue')
}
]
}
3,要在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置:
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 <router-view> 中
path: 'profile',
component: UserProfile
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 会被渲染在 User 的 <router-view> 中
path: 'posts',
component: UserPosts
}
]
}
]})
4,当嵌套子路由时,也可以设置匹配不到的路由页面展示
const router = new VueRouter({
routes: [
{
path: '/user/:id', component: User,
children: [
// 当 /user/:id 匹配成功,
// UserHome 会被渲染在 User 的 <router-view> 中
{ path: '', component: UserHome },
]
}
]})
6,编程式的导航
1,router.go(n):在 history 记录中向前或者后退多少步。相当于window.history.go(n)
7,命名视图
1,在同一个页面展示多个视图,如果不用嵌套,只能采用命名视图来实现了
<div>
<h1>User Settings</h1>
<NavBar/>
<router-view/>
<router-view name="helper"/>
</div>
{
path: '/settings', // 你也可以在顶级路由就配置命名视图
component: UserSettings,
children: [{
path: 'emails',
component: UserEmailsSubscriptions
}, {
path: 'profile',
components: {
default: UserProfile,
helper: UserProfilePreview // 是通过helper容器来展示的
}
}]
}
8,重定向和别名
- 重定向
{ path: '/a', redirect: { name: 'foo' }}
- 别名
{ path: '/a', component: A, alias: '/b' }
9,HTML5 History 模式
1,vue-router:默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的URL,于是当 URL 改变时,页面不会重新加载。
2,History 与 hash 区别
- hash 就是指 url 尾巴后的 # 号以及后面的字符,history没有底带#,外观上比hash 模式好看些
- 原理的区别(原理)
- hash 能兼容到IE8, history 只能兼容到 IE10;
- 由于 hash 值变化不会导致浏览器向服务器发出请求,基本都是使用 hash 来实现前端路由的。
3,不用hash模式方法
const router = new VueRouter({
mode: 'history',
routes: [...]
})
10,导航守卫
参数或查询的改变并不会触发进入/离开的导航守卫
- 全局前置守卫
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
// 如果用户未能验证身份,则 `next` 会被调用两次
next()
})
注:
to: 即将要进入的目标 路由对象
from: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
- next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址
- 全局后置钩子:可以注册全局后置钩子,但是这些钩子不会接受 next 函数也不会改变导航本身
- 路由独享的守卫
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]})
- 组件内的守卫
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
// 用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。
}}
11,$route.meta路由元信息
1,使用场景:meta制定业务所需要的信息
- 到此路由所需要的 权限 角色;如实例代码的权限认证,限制路由的访问;
- 对此路由是否采用 缓存
- 此路由进入页面的标题等信息
- 传递信息,可以用作路由记录
2,router
{
path: ‘/test’,
name: ’test’,
component:()=>import(“@/components/test”),
meta:{
title:’测试页面’, //配置title
keepAlive: true //是否缓存
requiredAuth: true //配置是否需要权限
}
}
①配置次路由的标题title
router.beforeEach((to,from,next) => {
if(to.meta.title) {
document.title = to.meta.title //配置title
}
next()
})
②配置组件是否需要缓存
//需要被缓存的路由入口
<keep-alive>
<router-view v-if=“$route.meta.keepAlive"></router-view>
</keep-alive>
12,滚动行为
- 导航完成之后获取:在 created 中进行调用
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滚动到哪个的位置
return { x: 0, y: 0 }
}
})
13,路由懒加载
为什么要使用?
答:为给客户更好的客户体验,首屏组件加载速度更快一些,解决白屏问题。
import Vue from ‘vue’
import Router from ‘vue-router’
export default new Router({
routes:[
{
path:’/Login’,
name:’Login’,
component: resolve => require([‘@/components/Login'],resolve) //懒加载写法1
component: ()=>import("@/components/Login")//懒加载写法2
}
]
})