目录
路由简述
vue-router
vue-router的安装配置与使用
路由重定向
嵌套路由
嵌套路由重定向
命名路由
动态路由
路由简述
路由(英文:router)就是对应关系。单页面应用程序(SPA)指的是一个web网站只有唯一一个HTML页面,所有组件的展示与切换都在这唯一的一个页面内完成。此时,不同组件之间的切换需要通过前端路由来实现。前端路由:通俗的概念是Hash地址与组件之间的对应关系。
路由的分类:
一个路由就是一组映射关系(key-value)。key为路径,value可能是function或component
1)前端路由:value是component,用于展示页面的内容;当浏览器的路径改变时,对应的组件就会显示。
2)后端路由:value是function,用于处理客户端提交的数据;服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据。
前端路由的工作方式:
1)用户点击了页面上的路由链接
2)URL地址栏中的Hash值发生了变化
3)前端路由监听到了Hash地址的变化
4)前端路由把当前Hash地址对应的组件渲染到浏览器中
vue-router
vue-router是vue的一个插件库,专门用来实现SPA应用。vue-router是vue.js官方给出的路由解决方案。它只能结合vue项目进行使用,能够轻松的管理SPA项目中组件的切换,其官方文档地址:vue-router 。
vue-router的安装配置与使用
1)安装 vue-router 包:(注意:如果使用vue2项目需指定版本,默认下载会下载最新版本,最新版本只兼容vue3项目,这点切记。我这里指定版本匹配vue2项目,如果是vue3项目的话,不指定版本默认下载即可。)
npm install vue-router@3.5.2 -S
执行命令后可能会出现如下错误:
报错提示:
Fix the upstream dependency conflict, or retry:修复上游依赖关系冲突,或重试
this command with --force, or --legacy-peer-deps:此命令带有--force或--legacy peer deps
to accept an incorrect (and potentially broken) dependency resolution. :以接受不正确(并且可能被破坏)的依赖性解析。
主要原因:
npm7 以上的版本,新增了一个对等依赖的特性,在以前的版本上,只会显示警告,但是还是可以安装成功,然而在新的版本是,npm 安装依赖则会直接报错,无法安装,这也是为了应用更加健壮而加的新的特性吧!
解决方法:
如果要保持旧的安装模块方法,可以尝试 npm install 加
入
--legacy peer deps 参数,这个参数保持跟旧版本一样的安装模块,忽略对等依赖。或者加入 --force 绕过冲突。
2)创建路由模块:(在src源代码目录下,新建router/index.js路由模块,并初始化如下代码)
// 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()
// 4.向外共享路由的实例对象
export default router
3)导入并挂载路由模块:
我们在 main.js 文件下导入路由模块,目的是为了拿到路由的实例对象。
4)声明路由链接和占位符:
当安装和配置了 vue-router 后,就可以使用 router-link 来替代普通的a链接了,使用router-link后,就不用再书写a链接必须写的 # 了。
<!-- <a href="#/home">首页</a> -->
<router-link to="/home">首页 </router-link>
<router-link to="/movie">电影 </router-link>
<router-link to="/about">关于</router-link>
只要在项目中安装和配置了 vue-router,就可以使用 router-view 这个组件了,作用:占位符。
<router-view></router-view>
声明完路由链接和占位符之后,我们就需要在 router 文件夹下声明我们的路由规则以及要导入我们要展示到页面的组件。
// 导入Vue和VueRouter的包
import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入需要的组件
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'
// 调用Vue.use()函数,把VueRouter安装为Vue的插件
Vue.use(VueRouter)
// 创建路由的实例对象
const router = new VueRouter({
// routes是一个数组,作用:定义 “hash地址” 和 “组件” 之间的对应关系。
routes: [
// 路由规则
{ path: '/home', component: Home },
{ path: '/movie', component: Movie },
{ path: '/about', component: About }
]
})
// 向外共享路由的实例对象
export default router
补充:
浏览器的历史纪录有两种写入方式:分别是push和replace,push是追加历史记录,replace是替换当前记录,路由跳转的时候默认为push。
replace属性的作用是:控制路由跳转时操作浏览器历史记录的模式
开启replace模式:<router-link replace ......>内容</router-link>
路由重定向
路由重定向:用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件页面,通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向:
嵌套路由
通过路由实现组件的嵌套展示,叫做嵌套路由,如下图所示:
通过children属性声明子路由规则,即在 src/router/index.js路由模块中,导入需要的组件,并使用children属性声明子路由规则:
// 导入需要的组件
import Tab1 from '@/components/tabs/Tab1.vue'
import Tab2 from '@/components/tabs/Tab2.vue'
// 创建路由的实例对象
const router = new VueRouter({
routes: [
// 路由规则
{
path: '/about',
component: About,
children: [ // 通过children属性,嵌套声明子级路由规则
// 注意:子路由规则的路径 path 一般前面就不需要加 "/" 了。
{ path: 'tab1', component: Tab1 }, // 访问 /about/tab1 时,展示 Tab1 组件
{ path: 'tab2', component: Tab2 } // 访问 /about/tab2 时,展示 Tab2 组件
]
}
]
})
嵌套路由重定向
当为嵌套的子路由规定页面跳转的地址时,如下操作即可:
当然我们也可以通过设置默认子路由实现:如果 children 数组中,某个路由规则的path值为空字符串,则这条路由规则叫做:“默认子路由“。 也能达到和重定向相同的效果,看具体情况设置。
命名路由
命名路由的作用是简化要书写的完整路径,为什么要简化呢?举个例子比如你在开发过程中有一个路径十分的长,如果你不简化路径的话,写的路径代码太长显得十分臃肿,说白了就不好看,如下
这里我们就需要借助命名路由来简化我们书写的路径了,即在路由规则上加一个name属性,如下
如果想为子路由链接添加命名路由也可以通过上面的方式进行添加。
如果想配合传递参数的话,可以通过以下的方式。
动态路由
动态路由是指:把Hash地址中可变的部分定义为参数项,从而提高路由规则的复用性。在 vue-router 中使用英文的冒号(:)来定义路由的参数项。代码如下:
// 路由的动态参数以 : 进行声明,冒号后面的是动态参数的名称
{ path: '/movie/:id', component: Movie }
// 将下面三个路由规则,合并成一个,提高了路由规则的复用性
{ path: '/movie/1', component: Movie }
{ path: '/movie/2', component: Movie }
{ path: '/movie/3', component: Movie }
那么我们如何判断我们获取的是哪个id页面的路径呢?我们可以通过 this.$route 为路由的 “参数对象” 来知道,如下:
当然拿到id不仅可以通过上面的方式,使用props属性也可以,如下:
props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传递给其组件
其他方式:
props值为对象,该对象中的所以key-value的组合最终都会通过props传给其组件。
props:{a:100}
props值为函数,该函数返回的对象中每一组key-value都会通过props传递给其组件
props(route){ return { id:route.query.id, title:route.query.title } }
注意:
1)在上文介绍的hash地址中,/ 后面的参数项,叫做路径参数,需通过 this.$route.params来访问路径参数。
2)在hash地址中,?后面的参数,叫做查询参数,需通过 this.$route.query 来访问查询参数
注意:fullPath包含完整的路径参数和查询参数,而path路径值包含路径参数。
3)路由组件通常存放在pages文件夹下,一般组件通常存放在components文件夹
4)通过切换按钮,“隐藏”了路由组件,默认是被销毁的,需要的时候再去挂载。
5)每个组件都有自己的 $route 属性,里面存储着自己的路由信息。
6)整个应用只有一个router,可以通过组件的 $router 属性获取到。