路由原理
- 传统开发方式 url改变后 立刻发起请求,响应整个页面,渲染整个页面
 SPA 锚点值改变后 不会发起请求,发起ajax请求,局部改变页面数据
- 页面不跳转 用户体验更好
 
SPA
- single page application(单页应用程序)
 前端路由
- 锚点值监视
 - ajax获取动态数据
 - 核心点是锚点值
 
- 前端框架 Vue/angular/react都很适合开发单页应用
 
基本使用
- vue-router
 - 其是vue的核心插件
 - 1:下载 
npm i vue-router -S - 1.5(重要):安装插件
Vue.use(VueRouter); - 2:在main.js中引入vue-router对象 
import VueRouter form './x.js'; - 3:创建路由对象 
var router = new VueRouter(); 4:配置路由规则
router.addRoutes([路由对象]);- 路由对象
{path:'锚点值',component:要(填坑)显示的组件} 
- 路由对象
 5:将配置好的路由对象交给Vue
- 在options中传递-> key叫做 router
 
- 6:留坑(使用组件) 
<router-view></router-view> 
router-link
- to
<router-link to="/xxx/x">点我</router-link> - 帮助我们生成a标签的href
 锚点值代码维护不方便,如果需要改变锚点值名称
- 则需要改变 [使用次数 + 1(配置规则)] 个地方的代码
 
命名路由
- 1:给路由对象一个名称 
{ name:'home',path:'/home',component:Home} 2:在router-link的to属性中描述这个规则
<router-link :to="{name:'home'}></router-link>"- 通过名称找路由对象,获取其path,生成自己的href
 
- 大大降低维护成本,锚点值改变只用在main.js中改变path属性即可
 
参数router-link,
Vue.prototype.xxx = {add:fn}- 所有组件中,使用this.xxx就能拿到这个对象
 查询字符串
- 1:配置
:to="{name:'detail',query:{id:hero.id} }" - 2:规则 
{name:'detail',path:'/detail',component:Detail} - 3:获取 
this.$route.query.id - 4:生成 
<a href="/detail?id=1"> 
- 1:配置
 path方式
- 4:生成 
<a href="/detail/1"> - 1:配置 
:to="{name:'detail',params:{id:hero.id} }" - 2:规则 
{ name:'detail',path:'/detail/:id'} - 3:获取 
this.$route.params.id 
- 4:生成 
 查询字符串配置参数
- router-link一次
 - 获取的时候一次
 
path方式配置参数
- router-link一次
 - 规则配置的时候声明位置
 - 获取的时候一次
 
总结书写代码注意事项
- path方式需要在路由规则中声明位置
 
别名
/a的别名是/b,意味着当用户访问/b时,URL会保持为/b,但是路由匹配则为/a,就像用户访问/a一样。
{ path: '/a', component: A, alias: '/b' }重定向
// 方式一:字符串路径path
{ path: '/a', redirect: '/b' }
// 方式二:name
{ path: '/a', redirect: {name: 'b'} }
// 方式三:动态返回重定向目标
{ path: '/a', redirect: to => {
  // 方法接收 目标路由 作为参数;return 重定向的 字符串路径/路径对象 
}}阶段总结
- vue-router使用步骤 : 1:引入 2:安装插件 3:创建路由实例 4:配置路由规则 5:将路由对象关联vue 6:留坑
 router-link to="/xxx" 命名路由
- 在路由规则对象中 加入name属性
 - 在router-link中 :to="{ name:"xxx'} "
 
- $route 路由信息对象,只读对象
 - $router 路由操作对象,只写对象
 下图来自vue-router源码
 在这里插入图片描述](/img/bVyXj)](https://img-blog.csdnimg.cn/20191225144125750.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3RqeDExMTEx,size_16,color_FFFFFF,t_70)
- Vue.use(插件对象); // 过程中会注册一些全局组件,及给vm或者组件对象挂在属性
 - 给vm及组件对象挂在的方式  :  Object.defineProperty(Vue.prototype,'$router',{
 get:function () {
 return 自己的router对象; }
})
 
嵌套路由
需要根据锚点值的改变,仅仅变化上图中的Profile到Posts组件,即可使用嵌套路由
代码思想
1:router-view的细分
- router-view第一层中,包含一个router-view
 
- 2:每一个坑挖好了,要对应单独的组件
 
- 使用须知: 1:router-view包含router-view 2:路由children路由
 
路由守卫
它其实就是一个路由改变的事件回调函数
全局路由守卫
- 前置
router.beforeEach((to, from,next) => {}) - 后置
router.afterEach((to, from) => {}) 
- 前置
 路由独享的守卫
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) =>{ // ... } } ] })
组件内的守卫
const Foo = { template: `...`, beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当守卫执行前,组件实例还没被创建 // 但是,可以这样用 next(vm => { // 通过 `vm` 访问组件实例-> 未来的组件this vm.msg = '数据在此'; }) }, beforeRouteUpdate (to, from, next) { // 触发条件见下文 // 可以访问组件实例 `this` }, beforeRouteLeave (to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` } }beforeRouteUpdate的触发条件(动态路由参数变化时)
- 1:路由配置
 {path:"/xxx/:id"}- 2:router-link
 <router-link to="/xxx/1"<router-link to="/xxx/2"
next
- 放行next();
 - 取消本次导航(url恢复成点击前的)
next(false) 重定向
next('/xxx') // 或者 next({name:'路由对象的name属性'});
to||from
- 该对象中的.fullPath属性比较常用,也就是当前的url
 
守卫meta属性的应用
路由meta元数据 -> meta是对于路由规则是否需要验证权限的配置
- 路由对象中 和name属性同级 
{ meta:{ isChecked:true } } 
- 路由对象中 和name属性同级 
 路由钩子 -> 权限控制的函数执行时期
- 每次路由匹配后, 渲染组件到router-view之前
 router.beforeEach(function(to,from,next) { // 判断to或from的fullPath即可 } )
编程导航
- 1: 跳到指定的锚点,并显示页面 
this.$router.push({ name:'xxx',query:{id:1},params:{name:'abc'} }); - 2: 配置规则 
{name:'xxx',path:'/xxx/:name'} 3: 根据历史记录.前进或后退
this.$router.go(-1|1);- 1代表进一步,-1是退一步
 
过渡效果及缓存
我们需要在路由改变时变化页面,ok!同时我们希望加上一些淡入淡出等效果,就可以用上transition内置组件
另外,考虑到缓存问题,就加上keep-alive组件结合使用
因此,你看到是这样的
<transition>
  <keep-alive>
    <router-view></router-view>
  </keep-alive>
</transition>