什么是路由?
Hash 地址与组件之间的对应关系
vue-router 路由的模式
hash 、history 、abstract 三种模式
1. hash :使用 URL hash 值作路由。支持所有的浏览器,包括不支持 HTML5 History Api 的浏览器
2. history:依赖 HTML History Api 和服务器配置( SSR 必须采用 history 模式,因为 hash 的路由提交不到服务器上)
3. abstract :支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果没有发现浏览器的API,路由会自动强制进入这个模式。
前端路由的工作原理?
1.用户点击了页面上的路由链接;
2.导致URL地址栏中的Hash值发生了变化;
3.前端路由监听到了Hash地址变化;
4.前端路由把当前Hash对应的组件渲染到浏览器中;
vue-router 安装和配置的步骤
1.安装vue-router 包
npm i vue-router@3.5.2 -S
2.创建路由模块,并声明路由的匹配规则
在src 源代码目录下,新建router/index.js,并初始化如下代码:
// 1. 导入 Vue 和 VueRouter 的包
import Vue from 'vue'
import VueRouter from 'vue-router'
// 2. 调用 Vue.use() 函数,把VueRouter 安装为 Vue 插件
Vue.use(VueRouter)
// 3. 创建路由的实例对象
const router = new VueRouter({
routes: [ // 在routes 数组中,声明路由的匹配规则
// path 表示要匹配的 hash 地址(都用小写); component 表示要展示的路由组件
{ path: '/home', component: '@/component/Home.vue' },
{ path: '/about', component: '@/component/About.vue' },
]
})
// 4. 向外共享路由的实例对象
export default router
3.导入并挂载路由模块
在src/main.js 入口文件中,导入并挂载路由模块。示例代码如下:
import Vue from 'vue'
import App from './App.vue'
// 1. 导入路由模块
import router from '@/router'
new Vue({
render: h => h(App),
// 2. 挂载路由模块
router
}).$mount('#app')
4.声明路由链接和占位符
在 src/App.vue 组件中,使用 vue-router 提供的 <router-link> 和 <router-view> 声明路由链接和占位符
<template>
<div class="app-container">
<h1>App 组件</h1>
<!-- 1. 定义路由链接 -->
<router-link to="/home">首页</router-link>
<router-link to="about">关于</router-link>
<hr>
<!-- 2. 定义路由占位符 -->
<router-view></router-view>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
嵌套路由
动态路由
动态路由: 把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性
// 1. 路径参数传参规则
{ path: 'home/:id', component: '@component/Home.vue' }
// 页面上使用 $route.params 接收
this.$route.params.id
// 2. 使用 props 传参 ,并接收参数
{ path: 'home/:id', component: '@component/Home.vue', props: true }
<template>
<div>
{{id}}
</div>
</template>
<script>
export default {
name: '',
props: ['id'],
}
</script>
路径参数 & 查询参数
在 hash 地址中, / 后面的参数项,叫做“路径参数”,? 后面的参数项,叫做“查询参数”
this.route 中,path 只是路径部分;fullPath 是完成的地址
声明式导航 & 编程式导航
在浏览器中,点击链接实现的导航方式叫做声明式导航( 普通网页中点击 <a> 链接、 vue项目中点击 <router-link> )
在浏览器中,调用API方法实现导航的方式叫做编程式导航( 普通网页中调用 location.href 跳转的方式、 vue-router的API)
vue-router 中的编程式API
1. this.$router.push('hash 地址')
- 跳转到指定 hash 地址,并增加一条历史记录
2. this.$router.replace(' hash 地址')
- 跳转到指定的 hash 地址,并替换掉当前的历史记录
3.this.$router.go(数值 n) ===》$router.back() 前进 $router.forward() 后退
- 实现导航历史前进、后退
完整的 vue-router 导航解析流程
- 导航被触发
- 在失活的组件里调用 beforeRouteLeave 守卫
- 调用全局 beforeEach 守卫
- 在复用组件里调用 beforeRouteUpdate 守卫
- 调用路由配置里的 beforeEnter 守卫
- 解析异步路由组件
- 在被激活的组件里调用 beforeRouteEnter 守卫
- 调用全局 beforeResolve 守卫
- 导航被确认
- 调用全局 afterEach 钩子
- DOM 更新
- 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数
导航钩子
全局的: 前置守卫( beforeEach )、后置钩子( afterEach )、解析守卫( beforeResolve )
单个路由独享的:beforeEnter
组件级:beforeRouteEnter 、beforeRouteUpdate、beforeRouteLeave
beforeRouteEnter : 不能获取组示例 this ,因为在执行路由钩子函数 beforeRouteEnter ,组件还没有被创建出来
全局前置守卫
import VueRouter from 'vue-router'
import Vue from 'vue'
Vue.use(VueRouter)
// 创建路由实例对象
const router = new VueRouter
const ruleArr = ['/home', '/detail']
// 全局前置守卫
router.beforeEach((to, from, next) => {
// to 是将要访问路由的信息对象
// from 是将要离开的路由信息对象
// next 是一个函数,调用 next() 表示放行,允许这次路由导航,next('hash地址'),next(false)停留在当前页面
// 权限控制,访问指定页面需要先判断是否登录
if(ruleArr.indexOf(to.path) != -1) {
}
})