一、Vue-Router作用

个人理解:
就是拼接完整的URL,负责了端口号之后的路径[参数]这部分。

URL:http://<host>:<port>/<path>?<searchpart>

二、路由配置及使用

1、配置参数

“path” 用于配置访问路径
“name” 用于给该路由命名
“component” 表示需要映射的组件
“redirect”表示重定向
“children”用于路由嵌套

2、默认路径(相对路径和绝对路径)

const routes = [
	{
	  path: '/',
	  redirect: '/root',
	},
	{
	  path: '/root',
	  name: 'root',
	  component: Root,
	},
]

注意
(1)path: '/'配置的是根路径:/。反映到URL上就是/<path>/部分。
(2)redirect: '/root',是指将根路径(/)重定向到根路径下的root路径下(/root)
(3)path: '/root',需要带“/”,表示根路径下的root路径下(/root)

(1)带“/”和不带“/”的区别

/,表示绝对路径/是根路径,表示的是/<path>/部分。
不带/,表示相对路径,相对于父路由下的路径(如果没有则找到根路径)
注意:
一般是在pathredirect里可能用到“/”

父路由如何判断方式?
从当前相对路径的代码行(path、redirect都可以)开始,往上找一个包裹他的路由就是父路由

3、路由嵌套(路由重定向)

const routes = [
  {
    path: '/',
    redirect: '/root',
  },
  {
    path: '/root',
    name: 'root',
    component: Root,
    redirect: '/root/child1',
    children: [
      // {    // 等效于 外层的  redirect: '/root/child1',
      //   path:'',
      //   redirect:'child1'
      // },
      {
        path: 'child1',  // 等效于'/root/child1'
        name: 'child1',
        component: child1,
        redirect: '/root/child1/child3',
        children:[
          {
            path: 'child3', // 等效于'/root/child1/child3'
            name: 'child3',
            component: child3,
          }
        ]
      }
    ]
  }
]

在这里插入图片描述

redirect: '/root/child1',表示重定向到根路径下的root下的child路径

注意
(1)如果写成redirect: 'root/child1',也可以到http://192.168.1.8:8080/root/child1,是因为root的相对路径本就是根路径/,所以没问题
(2)如果写成redirect: '/child1',路径会到http://192.168.1.8:8080/child1,因为 '/child1'的意思是根路径下的child1路径
(3)如果写成redirect: 'child1',等效于redirect: '/child1'
(4)等效于children里的{ path:'', redirect:'child1' }

第一个children下的配置

注意
path: 'child1',不需要写“/”
不写“/”代表相对路径,先找他的父组件/root,最终等效于/root/child1
写了“/”代表绝对路径,直接匹配/child1

children的多层嵌套(第二个children下的配置)

注意
redirect: '/root/child1/child3'等效于redirect: 'child1/child3',都是指向/root/child1/child3
还是相对路径和绝对路径的问题,不过第一种写法更利于阅读

4、动态路由匹配

在这里插入图片描述

参数获取

一个“路径参数”使用冒号:标记。
通过this.$route.params.[id]获取路径中的变量,[id]只跟在routes里定义的变量名有关
在vue文件中需要写成this.$router.push('/user/kobe/id/111')

5、路由传参

(1)vue文件中传参

注意:
(1)通过query传参,既可以写path,也可以写name。通过this.$route.query.id获取参数
(2)通过params不能写path,只能写name + params。通过this.$route.params.id获取参数

//子路由配置
{
  path: '/child1,
  name: 'child1',
  component: child1
}
//父路由编程式传参(一般通过事件触发)
root1 () {
  // query传参
  this.$router.push({ path: '/child1', query: { id: '123' } })   // /child1?id=123
  this.$router.push({ name: 'child1', query: { id: '456' } })   // /child1?id=456
  // params传参
  this.$router.push({ name: 'child1', params: { id: '789' } })
}

(2)routes里传参

注意:
(1)redirect重定向可以使String类型,也可以是Object类型,Object类型可以携带参数
(2)不能在路由对象中单独添加queryparams属性,没有这两个属性,参考下例的root路由

const routes = [
  {
      path: '/',
      // redirect: '/root', // 无参数情况
      // query传参
	  redirect: {path:'/root', query:{ id: '123' }},  // /root?id=123
	  // redirect: {name:'root', query:{ id: '456' }},  // /root?id=456
	  // params传参
	  // redirect: {name:'root', params:{ id: '789' }},
  },
  {
	  path: '/root',
	  name: 'root',
	  component: Root,
      // query:{      错误写法
      //   id: '123'
      // }
	},
]

6、 keep-alive使用

作用

可以使被包含的组件保留状态(数据保存),避免组件频繁的被创建和销毁
它们有两个非常重要的属性:
include - 字符串或正则表达,只有匹配的组件会被缓存
exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存

使用

keep-alive包裹router-view时,对应所有路径的组件都会被缓存

<keep-alive exclude="Profile,User">  // Profile,User这两个组件不缓存,中间不要加空格
   <router-view></router-view>
</keep-alive>

场景(保存页面离开时的数据)
在这里插入图片描述

7、路由的懒加载

// 路由的懒加载
const child1 = () => import(/* webpackChunkName: "child1" */ '../views/router-test/child1.vue')

const routes = [
  {
    path: '/child1',
    name: 'child1',
    component: child1,
  }
]

注意

  1. 懒加载,其实是指import( '../views/router-test/child1.vue')
  2. /* webpackChunkName: "child1" */webpack的魔法语句,是为了分包用的
  3. import只能写字符串路径,不支持变量。例如a ='../views/router-test/child1.vue' ,路由component: () => import(a) ,这样会报错
  4. 一定要用变量的时候,可以通过字符串模板来提供部分信息给webpack;例如import(./path/${myFile}), 这样编译时会编译所有./path下的模块,但运行时确定myFile的值才会加载,从而实现懒加载。

8、Not Found路径

在这里插入图片描述

三、动态添加路由

在这里插入图片描述

四、删除路由

在这里插入图片描述

五、导航守卫

to参数: Route对象, 即将跳转到的Route对象
from参数: Route对象, 从哪一个路由对象导航过来的

返回值问题:
1.false: 不进行导航
2.undefined或者不写返回值: 进行默认导航
3.字符串: 路径, 跳转到对应的路径中
4.对象: 类似于 router.push({path: “/login”, query: …})
在这里插入图片描述

六、刷新当前路由

方法1<router-view :key='$route.fullPath'>

fullPath:可以识别当前页面路由的完整地址,当地址发生改变(包括参数改变)则重新渲染页面(例如动态路由参数的变化)

方法2this.$router.go(0)
方法3location.reload()

方法2和方法3,这两种都可以刷新当前页面的,缺点就是相当于按ctrl+F5 强制刷新那种,整个页面重新加载,会出现一个瞬间的空白页面,用户体验不好,所以不推荐使用。

七、新窗口打开路由页面

if (file.fileType === 'ofd') {
  let newUrl = this.$router.resolve({
    // path: `/openofdfile?ofdUrl=${fileUrl}` // 跳转的路由地址,用path: 'path地址'也可以
    name: 'openofdfile',
    query: {
      ofdFile: JSON.stringify(file.fileUrl)
    }
  })
  window.open(newUrl.href, '_blank')
}

八、BUG 处理

8.1 刷新当前路由出现白屏错误

// vue.config.js
const BASE_URL = process.env.NODE_ENV === 'production' ? './' : '/'

8.2 f5刷新保持当前菜单选择

  created () {
    // 刷新路由保持当前状态
    this.activeIndex = this.$route.path
  }

九、不同的路由加载相同的组件,进行页面的强制刷新

9.1 背景

正常情况:比如A路由'/path1'加载组件cpn,B路由'/path2'也是加载组件cpn,组件cpn的生命周期只会执行一次。

9.2 强制刷新的解决方案

<router-view :key="$route.query.key || Math.random()"></router-view>

router-view加个key值,可以是random随机数,这样路由在跳转时,由于key值变化,会导致组件重新加载

Logo

前往低代码交流专区

更多推荐