路由是一种映射关系(接口和服务)
vue中的路由就是路径和组件的映射关系
使用路由理由
在前端,路由的作用,就是实现业务场景切换
优点:
- 整体不刷新页面,用户体验更好
- 数据传递容易,开发效率高
缺点:
- 开发成本高(需要学习专门知识)
- 首次加载会比较慢一点
单页面应用
- 所有业务都在一个页面编写,只有一个html
- 好处:开发效率高,用户体验好
- 单页面依赖路由切换场景
使用路由系统步骤
# 下载vue-router模块到当前工程 yarn add vue-router
# 在main.js中引入VueRouter函数 import VueRouter from 'vue-router'
# 添加到Vue.use()身上,– 注册全局RouterLink和RouterView组件 Vue.use(VueRouter)
# 创建路由规则数组 – 路径和组件名对应关系 const routes = [ { path: "/find", component: Find }, { path: "/my", component: My }, { path: "/part", component: Part } ]
# 创建路由对象 --传入规则 const router = new VueRouter({ routes })
# 把路由对象注入到new Vue实例 new Vue({ # 渲染App文件(组件) render: (h) => h(App), router, # mount挂载到#app中 }).$mount("#app");
# 用router-view作为挂载点, 切换不同的路由页面(App.vue文件) <router-view></router-view>
全部步骤:下包/引入/注册/规则/路由对象/注入/挂载点
声明式导航
声明式导航-基础使用
- vue-router提供了一个全局组件 router-link
- router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)
- router-link提供了声明式导航高亮的功能(自带类名)
<template>
<div>
<h2>声明式导航 - 组件形式跳转</h2>
<ul>
<li>
<!-- 声明式导航页支持对象写法,通过 v-bind: 绑定即可 -->
<router-link :to="{ path: '/find' }">发现</router-link>
</li>
<li>
<router-link to="/my">我的</router-link>
</li>
<li>
<router-link to="/part">part页 </router-link>
</li>
</ul>
<h2>编程式导航 - JS形式跳转</h2>
<!-- 7. 路由挂载点:类似动态组件 <component/> -->
<!-- 🔔工作原理:根据路径,自动把 <router-view/> 替换成某个页面组件 -->
<router-view />
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
/* vue-router 的 router-link 标签路径匹配时自动添加的类名,常用于链接高亮 */
.router-link-exact-active {
color: red;
}
</style>
声明式导航 - 跳转传参
在router-link上的to属性传值, 语法格式如下
/path?参数名=值
/path/值 – 需要路由对象提前配置 path: “/path/参数名”
对应页面组件接收传递过来的值
- $route.query.参数名
- $route.params.参数名
方案一
//传参页面
<template>
<div>
<ul>
<li>
<!-- 跳转传参 -->
<!-- 方式一 /path?参数名=值 -->
<router-link to="/find?id=123">发现</router-link>
</li>
<li>
<router-link to="/my">我的</router-link>
</li>
</ul>
<hr />
<router-view />
</div>
</template>
<script>
export default {}
</script>
<style scoped>
/* 省略了 其他样式 */
.router-link-active {
color: white;
background: black;
}
</style>
//接收页面
<template>
<div>
<!--
声明式导航 - 传值给路由页面
方案1:
传值:
to="/path?参数名=值"
接收:
$route.query.参数名
方案2:
传值:
to="/path/值" (需要在路由规则数组中配置 /path/:参数名)
接收:
$route.params.参数名
PS:两种方案二选一即可,选择哪种看团队习惯。
-->
<li>
<router-link to="/find">{{ $route.query }}</router-link>
</li>
<li>
<router-link to="/find">{{ $route.query.id }}</router-link>
</li>
<hr />
<router-view></router-view>
</div>
</template>
<script>
export default {};
</script>
<style scoped>
/*
router-link-exact-active (精确匹配) url中hash值路径 与href属性值完全相同,设置此类名(用在二级)
router-link-active (模糊匹配) url中hash值,包含href属性值这个路径(用在一级)
*/
.router-link-exact-active {
color: yellow;
}
</style>
方案二
<template>
<div>
<ul>
<li>
<!-- 跳转传参 -->
<!-- 方式二 /path/值 需要在路由规则数组中配置 -->
<li>
<router-link to="/part/我是传过去的内容">part页</router-link>
</li>
</ul>
<hr />
<router-view />
</div>
</template>
<script>
export default {};
</script>
<style scoped>
/* 省略了 其他样式 */
.router-link-active {
color: white;
background: black;
}
</style>
//路由配置 /path/:参数名
{
path: "/part/:ppp",
component: Part,
},
//接收页
<template>
<div>
<li>{{ $route.params.ppp }}</li>
<li>{{ $route.params }}</li>
</div>
</template>
<script>
export default {};
</script>
路由重定向
匹配path后,强制跳转path路径
网页打开url默认hash值是/路径(默认路由)
redirect是设置要重定向到哪个路由路径的
const routes = [
{
path: '/',
// redirect 重定向,可以理解为替换,当路由匹配 / 的时候替换成 /find
redirect: '/find',
}]
页面访问不在
找不到路径给个提示页面(404页面)
路由最后, path匹配*(任意路径) – 前面不匹配就命中最后这个
在路由规则数组中配置
const routes=[
// 404 书写在最后 (规则是从前往后逐个比较path,作为兜底存在)
{
path: '*',
component: NotFound,
}
]
更改路由在地址栏的模式
hash路由例如: http://localhost:8080/#/home
history路由例如: http://localhost:8080/home
在实例化路由对象时,通过传入mode选项和值修改来达到修改路由模式
const router = new VueRouter({
routes,
// 路由模式
// mode: 'hash' // 默认值,带 # 的模式
mode: 'history', // 不带 # 的模式,需要后端额外配置才能使用,VueRouter 官网有参考配置,让后端自己看
})
编程式导航
基础使用
用js代码来进行跳转----一般用于点击时需要判断后才跳转
语法:this.$router.push('对应的页面')
this.$router.push('/my')
1.基本使用:直接传字符串
this.$router.push('/part?id=123')
进阶使用
2. 进阶使用:传对象的形式,适用于参数较多的<复杂情况>
query写法:
this.$router.push({
path: '/part',
query: { id: 123, a: 'abc' },
})
parmas写法:
this.$router.push({
// 注意:path 会自动忽略 params
// path: '/part/789',
// 解决方案:1.路由数组中添加路径别名,2. 使用时通过 name 路径别名匹配路径
name: 'Part',
params: {
id: 789,
},
})
路由规则中也得设置name
{
// 添加路由规则,接收 /xxx 传递的参数
path: '/part/:id',
// 路径别名
name: 'Part',
component: Part,
},
嵌套和守卫
嵌套
现有的一级路由下, 再嵌套二级路由
步骤:1.创建需要用到的所有组件
2.main .js中配置二级路由
一级路由path从/开始定义
二级路由往后path直接写名字, 无需/开头
嵌套路由在上级路由的children数组里编写路由信息对象
const routes =[
{
path: "/find",
component: Find,
// 嵌套路由(children[])二级
children: [
// 二级重定向
{
path: "", //可以省略
// redirect重定向(path设置为空,就默认为Recommend)
redirect: "Recommend",
//默认为Recommend页面(如果redirect没写,只写了component)
component: "Recommend",
},
// path: "Ranking",Ranking大小写不影响
{ path: "Ranking", component: Ranking },
{ path: "Recommend", component: Recommend },
{ path: "SongList", component: SongList },
],
},
]
// 对应页面
<template>
<div>
<h1>一级路由</h1>
<!-- to属性的每一级路径都需要写/开头 如:/一级/二级-->
<li><router-link to="/find/Recommend">推荐页面</router-link></li>
<li><router-link to="/find/Ranking">排行榜页面</router-link></li>
<li><router-link to="/find/SongList">歌单页面</router-link></li>
<hr />
<!-- router-view路由挂载点 -->
<!-- Find.vue的的router-view负责发现音乐下的, 三个页面, 切换 -->
<router-view></router-view>
</div>
</template>
前置守卫
路由跳转之前, 先执行一次前置守卫函数, 判断是否可以正常跳转
在路由对象上使用固定方法beforeEach
// 目标: 路由守卫
// 场景: 当你要对路由权限判断时
// 语法: router.beforeEach((to, from, next)=>{//路由跳转"之前"先执行这里, 决定是否跳转})
// 参数1: 要跳转到的路由 (路由对象信息) 目标
// 参数2: 从哪里跳转的路由 (路由对象信息) 来源
// 参数3: 函数体 - next()才会让路由正常的跳转切换, next(false)在原地停留, next("强制修改到另一个路由路径上")
// 注意: 如果不调用next, 页面留在原地
// 例子: 判断用户是否登录, 是否决定去"我的音乐"/my
const isLogin = true; // 登录状态(未登录)
router.beforeEach((to, from, next) => {
if (to.path === "/my" && isLogin === false) {
alert("请登录")
next(false) // 阻止路由跳转
} else {
next() // 正常放行
}
})
next()放行, next(false)留在原地不跳转路由, next(path路径)强制换成对应path路径跳转