Vue-Router相关

164 阅读6分钟

路由是路径和组件的映射关系

为什么要使用路由?

ue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统的页面应用,是用一些超链接来实现页面切换和跳转的。在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换。

vue-router实现原理

SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面;vue-router在实现单页面前端路由时,提供了两种方式:Hash模式和History模式;

路由模式有哪些?

1、Hash模式:

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。 hash(#)是URL 的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页,也就是说 #是用来指导浏览器动作的,对服务器端完全无用,HTTP请求中也不会不包括#;同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;所以说Hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据

2、History模式:

由于hash模式会在url中自带#,如果不想要很丑的 hash,我们可以用路由的 history 模式,只需要在配置路由规则时,加入"mode: 'history'",这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

  • hash模式:

    • 浏览器中符号是“#”,#以及#后面的字符称之为 hash,又叫前端路由
    • 用 window.location.hash 读取
    • hash 虽然在 URL 中,但不被包括在 HTTP 请求中
    • hash 改变会触发 hashchange 事件
    • hash发生变化的url都会被浏览器记录下来,从而浏览器的前进后退都可以用
  • history模式:

    • history 采用 HTML5 的新特性
    • history 模式不仅可以在url里放参数,还可以将数据存放在一个特定的对象中
    • 它也有个问题:不怕前进,不怕后退,就怕刷新(如果后端没有准备的话,会分分钟刷出一个404来。Html5history在打包上线后需要后端支持配置),因为刷新是实实在在地去请求服务器的。 在生成路由对象出修改模式,mode: "history"

vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用,让构建单页面应用变得易如反掌。包含的功能有:

  • 嵌套的路由/视图表
  • 模块化的、基于组件的路由配置
  • 路由参数、查询、通配符
  • 基于 Vue.js 过渡系统的视图过渡效果
  • 细粒度的导航控制
  • 带有自动激活的 CSS class 的链接
  • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
  • 自定义的滚动条行为

vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统的页面应用,是用一些超链接来实现页面切换和跳转的。在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换。路由模块的本质 就是建立起url和页面之间的映射关系。

项目中的配置路由

引入vue    -----配置路由文件
import Vue from "vue";
 1.引入路由
import VueRouter from "vue-router";
 2.注册组件
Vue.use(VueRouter)
 3.定义路由规则
const routes = [
   {
       path:'/', //默认路由
       redirect:"/login"  //重定向
   },
   {
       path:'/login',
       component:()=>import("@/views/login.vue")
   }
]

 4.根据路由规则生成路由对象
const router = new VueRouter({
    routes
})
5.导出路由 
export default router
6.在main.js 引入路由,把路由注入到的new vue实例中  router
7.APP.vue设置挂载点   <router-view/>

配置路由根据业务需要来设置,基本的路由配置有:

重定向
  • 网页打开url默认hash值是/路径
  • (相当于替换) redirect是设置要重定向到哪个路由路径
  {
    path: "/",            // 默认hash值路径
    redirect: "/find"     // 重定向到/find
    // 浏览器url中#后的路径被改变成/find-重新匹配数组规则
  }
]
总结: 强制重定向后, 还会重新来数组里匹配一次规则
路由定义
引入路由文件
{
    path: "/part",
    component: Part
  },
  
  或者也可以这样写:
   {
       path:'/part',
       component:()=>import("@/views/part.vue")
   }
404页面

如果路由hash值, 没有和数组里规则匹配,默认给一个404页面

const routes = [
  // ...省略了其他配置
  // 404在最后(规则是从前往后逐个比较path)
  {
    path: "*",
    component: NotFound
  }
]

路由传参方式

先介绍两种导航,声明式导航和编程式导航两种。

声明式导航 - 基础使用
  1. vue-router提供了一个全局组件 router-link(另一个是router-view)
  2. router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)
  3. router-link提供了声明式导航高亮的功能(自带类名)
声明式导航--自带高亮类名
  • router-link-exact-active (精确匹配) url中hash值路径, 与href属性值完全相同, 设置此类名
  • router-link-active (模糊匹配) url中hash值, 包含href属性值这个路径
编程式导航 - 基础使用

语法:

    path: "路由路径",      // 都去 router/index.js定义
    name: "路由名"
})

例如:// this.$router.push('/my')
      // this.$router.push('/part/123')

1.编程式导航用JS代码跳转。特殊情况下才能使用,有一定的条件。如:判断用户已登录才跳转

2.声明式导航组件标签的形式跳转,相当于利用a标签的href属性

3、this.$router.replace()跳转到指定的url,但是history中不会添加记录,点击回退到上上个页面

4、this.$router.go(n)向前或者后跳转n个页面,n可以是正数也可以是负数。 后退: this.$router.back() ​ 前进 :this.$router.forward()

传参方式
声明式导航传参
  • to="/path?参数名=值" ---------- $route.query.参数名
  • to="/path/值 "– 路由配置 path: “/path/:参数名” -----------$route.params.参数名
编程式导航传参

进阶使用:传对象的形式,适用于参数较多的复杂情况,语法:

    path: "路由路径",
    query: {
    	"参数名": 值
    }
    或
   this.$router.push({
      path: "路由路径",
      name: "路由名",    //最好带上name
      params: {
		"参数名": 值
    }
    
    //路由配置要写
{
    path: "/part/:id",
    name:'part',
    component:Part
    // component: ()=>import("@/views/Part.vue")
  },
    
    
*    例如:*
      //querry方法
     this.$router.push({
         path: '/part',
         query: { id: 123, a: 'abc' },
       }),
      
          //params方法
       this.$router.push({
        name:  'part',
        params: {
           id: 789,
         },
      })
 
})

// 对应路由接收   $route.params.参数名   取值
// 对应路由接收   $route.query.参数名    取值

嵌套路由(二级路由)

就是在现有一级路由下再嵌套二级路由、三级路由...嵌套路由要 找准在哪个页面里写router-view(页面挂载)、router-link(页面展示)和对应规则里写children,配置路由的规则同上。

例如:
  const routes = [
  // ...省略其他
  {
    path: "/find",                        //一级路由
    name: "Find",
    component: Find,
    children: [
      {
        path: "recommend",
        component: Recommend             //二级路由
      },
    ]
  }
]

全局导航守卫

在路由跳转之前, 先执行一次前置守卫函数, 判断路由权限是否可以正常跳转。

使用场景:通常在登录页面对token值进行判断,来确认是否登录

语法: router.beforeEach((to, from, next)=>{

//路由跳转"之前"先执行这里, 决定是否跳转

})

参数1: 要跳转到的路由 (路由对象信息) 目标

参数2: 从哪里跳转的路由 (路由对象信息) 来源

参数3: 函数体 - next()才会让路由正常的跳转切换, next(false) 在原地停留, next("强制修改到另一个路由路径上")

例子:
const isLogin = true; // 登录状态(未登录)
router.beforeEach((to, from, next) => {
  if (to.path === "/my" && isLogin === false) {
    alert("请登录")
    next(false) // 阻止路由跳转
  } else {
    next() // 正常放行
  }
})