Vue-router 知识点总结

1,650 阅读5分钟

前言

vue-router是vue的一个重难点,要想一次就学废还是有点难度的,我花了一天多的时间整理,还算是比较全面的,相关的钩子之前写过了,这里就不在赘述了

什么是前端路由

通俗易懂的概念:Hash地址与组件之间的对应关系

前端路由的工作方式

  1. 用户点击了页面上的路由链接
  2. 导致了URL地址栏中的Hash值发生了变化
  3. 前端路由监听到了Hash地址的变化
  4. 把当前Hash地址对应的组件渲染到浏览器中

vue-router使用步骤

vue-router文档

  1. 安装
npm i vue-router

2.导入路由

import Vue from 'vue'
import VueRouter from 'vue-router'

3.注册 vue-router

// 在vue中,使用使用vue的插件,都需要调用Vue.use()
Vue.use(VueRouter)

4.设置匹配规则

const routes = [
    {
        path: '/',    //默认hash值路径
        redirect:'/find' // 重定向到find
    }
    ,
    {
        path: '/find',
        component: Find
    },
    {
        // 动态传参方式1:  :表示动态站位   id自定义
        path: '/My/:id',

        component: My,


        //动态传参方式2:开启 props 属性 传参
        props:true
    },
    {
        path: '/part',
        component: Part,
        redirect:'/part/tab1',
        // 通过 children 属性,声明嵌套子路由规则
        children: [
            {
                // 默认子路由: 如果children 数组中,某个路由规则的path值为空字符串,则默认展示该子路由
                // 子路由 path 后面不要加 / 
                path: 'tab1',
                component:Tab1
            },
            {
                path: 'tab2',
                component:Tab2
            }
        ]
    },
    {
        path: '/part/:name',
        component: Part,
        props: true
    },
    {   // 路由404 设置
        path: '*',
        component:NotFound
    }
]

5.实例化 router

const router = new VueRouter({
    routes,
    mode:"history",// 历史记录模式
})

6.导出 router

export default router

7.导入路由并挂载

在main点js中

// 全局导入路由
import router from './router'
new Vue({
  router,// 挂载路由
 
  render: h => h(App),
}).$mount('#app')

路由配置项

路由常用的配置项总共有如下几个:

  1. path:要请求的hash地址

  2. component:要展示的组件

  3. redirect:重定向,指定一个新的路由地址

  4. children:通过 children 属性,声明嵌套子路由规则

  5. name:配置中给某个路由设置名称

  6. props:路由解耦,路由传参的一种方式,针对动态路由

  7. meta:路由元信息,当前路由所携带的一些信息

vue路由 - 声明式导航

  1. vue-router提供了一个全局组件 router-link
  2. router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)
  3. router-link提供了声明式导航高亮的功能(自带类名)

声明式导航是写在template标签里,通过标签来触发

<template>
  <div>
    <div class="footer_wrap">
       //声明式导航会渲染成a链接
      <router-link to="/find">发现音乐</router-link>
      <router-link to="/my">我的音乐</router-link>
      <router-link to="/Part">朋友</router-link>
    </div>
    <div class="top">
       //要展示组件的占位符
      <router-view></router-view>
    </div>
  </div>
</template>

声明导航 - 类名区别

观察路由嵌套导航的样式

  • router-link-exact-active (精确匹配) url中hash值路径, 与href属性值完全相同, 设置此类名
  • router-link-active (模糊匹配) url中hash值, 包含href属性值这个路径

vue路由 - 编程式导航

编程式导航:通过调用JavaScript形式的API实现导航的方式,叫做编程式导航

除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

router.push(location, onComplete?, onAbort?)

注意:在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push

想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

当你点击 <router-link> 时,这个方法会在内部调用,所以说,点击 <router-link :to="..."> 等同于调用 router.push(...)

声明式编程式
<router-link :to="...">router.push(...)
// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

注意:如果提供了 pathparams 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path

const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

同样的规则也适用于 router-link 组件的 to 属性。

router.replace(location, onComplete?, onAbort?)

跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

声明式编程式
<router-link :to="..." replace>router.replace(...)

router.go(n)

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)

示例


// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)

// 后退一步记录,等同于 history.back()
router.go(-1)

// 前进 3 步记录
router.go(3)

// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)

路由嵌套

通过路由实现组件的嵌套展示,在现有的一级路由下, 再嵌套二级路由,叫做路由嵌套


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
        }
      ]
    }
  ]
})

路由传参

格式

this.$router.push({
    path: "路由路径"
    name: "路由名",
    query: {
    	"参数名": 值
    }
    params: {
		"参数名": 值
    }
})

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

格外注意: 使用path会自动忽略params

query参数

传参方式一

// <!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link>

方式二

<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{
		   path:'/home/message/detail',
		   query:{
			  id:m.id,
			  title:m.title
			  }
		  }">
{{m.title}}
</router-link>
			
接收参数
// 对应路由接收   $route.query.参数名
<li>消息编号:{{$route.query.id}}</li>
<li>消息标题:{{$route.query.title}}</li>

params参数

方式一

<!-- 跳转路由并携带params参数,to的字符串写法 -->
<router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link>

方式二

<!-- 跳转路由并携带params参数,to的对象写法 -->
<router-link :to="{
	name:'xiangqing',
	params:{
		id:m.id,
		title:m.title
		}
		}">
	{{m.title}}
</router-link>
接收参数
// 对应路由接收   $route.params.参数名
<li>消息编号:{{$route.params.id}}</li>
<li>消息标题:{{$route.params.title}}</li>

route 与 router区别

$route是路由的参数对象,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数。

$router是VueRouter的一个对象,通过Vue.use(VueRouter)和Vue构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由,包含了许多关键的对象和属性

路由的props配置

props为对象模式

值为对象,该对象中的所有key-value都会以props的形式传给组件,配置在哪个路由规则内就传给谁

const router = new VueRouter({
  routes: [
    {
      path: '/promotion/from-newsletter',
      component: Promotion,
      props: { newsletterPopup: false }
    }
  ]
})

props为布尔模式

值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件

const router = new VueRouter({
  routes: [
    {
      path: '/promotion/from-newsletter',
      component: Promotion,
      props:true
    }
  ]
})

props为函数模式

const router = new VueRouter({
  routes: [
    {
      path: '/search',
      component: SearchUser,
      props: route => ({ query: route.query.q })
    }
  ]
})

vue-router的两种模式hash 模式和 history 模式

hash模式与history模式是两种单页应用的路由模式:

hash模式 :

底层原理是通过hashChange 实现,使用 URL 的 hash 来模拟一个完整的 URL, 其显示的网络路径中会有 “#” 号,hash 虽然出现URL中,但不会被包含在HTTP请求中,对后端完全没有影响,因此改变hash后刷新, 也不会有问题

history模式:

底层原理是通过replaceState(), pushState()实现,history模式就是美化后的hash模式,路径中不包含“#”。依赖于Html5 的 history api 项目打包上线由于改变了地址, 刷新时会按照修改后的地址请求后端, 需要后端配置处理, 将地址访问做映射, 否则会404

解决方案:

为什么哈希模式打包不会出现问题?是因为哈希模式会默认去index页面,而history运行代码发现没有token会去login页面,但打包上线只有一个index页面,这就需要后端的配合,看后端是什么应用,但是原理都是一样的,需要后端把请求都转到index页面

宝,你都看到这了不给我一个star嘛?

PS:   如果内容有错误的地方欢迎指出(觉得看着不理解不舒服想吐槽也完全没问题);如果有帮助,欢迎点赞和收藏,转载请著明出处,如果有问题也欢迎私信交流