vue-router
介绍、使用
- Vue Router 是 Vue.js 官方的路由管理器
功能
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js transition组件的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
- 路由懒加载的使用
项目使用
下载路由模块
yarn add vue-router -S
在src文件夹中创建router文件夹,在其下创建index.js,
在其中引入vue-router模块并创建配置路由实例
import Vue from 'vue'
import Router from 'vue-router'
import Mine from '../components/Mine.vue'//引入Mine组件
Vue.use(Router) //通过use在vue全局注册使用
const routes=[//静态路由表 routes 分配地址
{
path:'/home',
component:()=>import('../views/Home.vue')//路由懒加载
}
{
path:'/Mine',
component:Mine
}
]
export default new Router({//实例化Router并将其接口暴露
routes,
mode:'history'//配置路由模式
})
在main.js主入口文件中引入router实例,并在创建的Vue实例中国通过 router 配置参数注入路由
...
import router from './router'
new Vue({
router,//让整个应用都有路由功能
render: h => h(App),
}).$mount('#app')
路由的内容渲染
<router-view>组件
<router-view> 组件是一个 functional 组件,渲染路径匹配到的视图组件。<router-view> 渲染的组件还可以内嵌自己的 <router-view>,根据嵌套路径,渲染嵌套组件。
路由链接激活(高亮) css样式
<router-link> Props
active-class
exact-active-class
<router-link tag='a' to="/" active-class="active" tag="li" exact>Home</router-link>
//active-class 默认值: "router-link-active"
//exact-active-class默认值: "router-link-exact-active"
...
<style>
.active{
color:red
}
</style>
嵌套路由的实现
Router 的参数中使用 children 配置,这样就可以很好的实现路由嵌套
注意在父组件Home中也要进行<router-view>占位渲染
routes=[ //静态路由表
{path:'/',
component:Home
},
{
path: '/user',
component: User,
children : [
{path:'',component:UserStart},
{path:':id',component:UserDetail},
{path:':id/edit',component:UserEdit}
]
}
]
命名路由
作用:方便
{
path: '/home',
component: Home,
//子路由
children: [
{
path: 'user', // 不能加/,以 / 开头的嵌套路径会被当作根路径
component: User,
name: 'user' //命名路由
},
{
path: 'junge',
component: Junge
}
]
},
- 使用:
<router-link :to = "{name:'user'}"/>
路由的重定向
{
path:’/’,
redirect:’/home’
} // 重定向,指向了home组件
命名视图
- component变成components
- 设置components中的default默
认组件显示对象 - 键值对,键名为⾃定义名称,键
值为组件对象 - router-view name=“键名”来进
⾏指定路由组件的显示操作
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
<router-view class="view one"></router-view>
<!-- 默认加载的Foo组件-->
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
路由组件传参
路由中 设置参数
{
path:'user/:id'
componenet:User
}
地址中 传递参数
<router-link :to="{ path: 'home' }">Home</router-link>
<!-- 命名的路由 -->
<router-link
:to="{ name: 'user', params: { userId: 123 }}">User</router-link>
<!-- 带查询参数,下面的结果为 /register?plan=private -->
<!-- 如果存在path,params属性会被忽略-->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>
目标l路由组件中 接收参数
{{$route.params.id}}
{{$route.query.plan}}
编程式导航
- push
this.$router.push('/home')
this.$router.push({name,params,query})
- push可以将我们的操作存放到浏览器的历史记录
- replace
this.$router.replace('/home')
this.$router.replace({name,params,query})
- replace没有将我们的操作存放到浏览器的历史记录, 效果为返回了二级
导航守卫(路由钩子)
“导航”表示路由正在发生改变。
正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。
1、全局守卫
作用于整个项目
-
作用:
- 守卫路由
- 进
- 举例: 携带数据进
- 出
- 举例: 事情完成才能出
- 进
- 守卫路由
-
导航守卫一共有三种形式
-
A: 全局导航守卫
- 全局前置守卫
router.beforeEach((to, from, next) => {...})
- fn中有三个参数
- 全局的解析守卫
router.beforeResolve((to, from, next) => {...})
- 在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
- 必须保证整个项目的守卫和异步路由组件解析完成
- 全局的后置守卫
router.afterEach((to, from) => {...})
- 可以做一些用户友好提示
- 全局前置守卫
-
B: 路由独享守卫
beforeEnter((to, from, next) => {...})
- 写在路由表中的守卫钩子
- 针对的是和当前路由相关的,那么其他与之不相关的路由,它是无法监听它的变化情况的
-
C: 组件内守卫
- 组件内的前置守卫
beforeRouteEnter((to,from,next)=>{})
- 导航进入组件时,调用
- this是访问不到的,如果非要访问this ,必须通过 next(vm=>{})访问
- 因为组件此时没有创建,所以没有this
- 案例: 数据预载(进入组件前就获得数据)
next(vm => { //vm指的就是组件 const result = JSON.parse(res.data.slice(7,-1)).rp_result.categorys vm.$set(vm.category,'categorys',result) })
- 组件内的后置守卫
beforeRouteLeave((to, from, next) => {...})
- 当好离开组件时,调用
- this是可以访问到 - 组件内的更新守卫( 路由传参和路由的接参 )
beforeRouteUpdate((to, from, next) => {...})
- 在当前路由改变,但是该组件被复用时调用
- 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
- 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
- 可以访问组件实例
this
- 组件内的前置守卫
-
-
功能: 导航守卫可以监听路由变化情况
-
名词
- 前置: 要进入当前路由 — 老师进入教室前
- 后置: 要离开当前路由 — 老师离开教室
-
关于next的使用
- next() 等价于 next( true ) 表示可以从当前路由跳转到目标路由
- next( false ) 表示不通过, 表示从当前路由跳转不到目标路由
- next(’/login’) 等价于 next({path:’/login’}) 跳转指定的路由
- next(’/login’) 等价于 next({path:’/login’,params,query})
- next( fn ) 数据预载
-
业务: 当我们进入到一个项目的首页时,但是当我们没有注册账号时,它主动跳转到了注册/登录页
router.beforeEach((to,from,next)=>{
const name = localStorage.getItem('name')
if( name || to.path === '/login' ){
//如果有 / --> /home
next()
}else{
next('/login')
}
})
滚动行为
<router-link to="/bar#anchor2">/bar#anchor2</router-link>
<p id='data'></p>
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
if(to.hash){
return {selector:to.hash}
}
// return 期望滚动到哪个的位置
}
})
<!-- bar组件-->
<div style:'height:1000px'></div>
<p id='data'></p>
<!-- 移动至此-->
路由懒加载
{
path:'/list',
name:'list',
component:()=>import('../views/List.vue')
},
{
path:'/mine',
component:()=>import('../views/Mine.vue')
},
```