路由的使用
路由介绍
1. 路由 - 介绍
(1)前端路由的本质, 对url的hash值进行改变和监听,切换挂载点的component组件
(2)vue 中的路由 : 是 hash 和 component 的对应关系, 一个哈希值对应一个组件
优点:
- 整体不刷新页面,用户体验更好
- 数据传递容易, 开发效率高
缺点:
- 开发成本高(需要学习路由)
- 首次加载会比较慢一点。不利于seo搜索引擎优化
2.路由 - vue-router模块
- 安装
yarn add vue-router
- 导入路由
import VueRouter from 'vue-router'
- 使用路由插件
// 在vue中,使用使用vue的插件,都需要调用Vue.use()
Vue.use(VueRouter)
- 创建路由规则数组
const routes = [
{
path: "/home",
component: MyHome
},
{
path: "/movie",
component: MyMovie
},
{
path: "/about",
component: MyAbout
}
]
- 创建路由对象 - 传入规则
const router = new VueRouter({ routes})
- 关联到vue实例
new Vue({
router
})
- 在使用地方加入router-view标签
<router-view></router-view>
总结: 下载路由模块, 编写对应规则注入到vue实例上, 使用router-view挂载点显示切换的路由
3. vue路由 - 链接导航
3.1 基础使用
目标: 可用全局组件router-link来替代a标签
- vue-router提供了一个全局组件 router-link: 作用用于提供路由链接
- router-link实质上最终会渲染成a链接 to属性等价于提供 href属性
- router-link提供了链接导航高亮的功能
<template>
<div>
<h1>App组件</h1>
<ul>
<li><router-link to="/home">首页</router-link></li>
<li><router-link to="/movie">电影</router-link></li>
<li><router-link to="/about">关于</router-link></li>
</ul>
<router-view></router-view>
</div>
</template>
<script>
export default {};
</script>
<style>
</style>
总结: 链接导航, 用router-link配合to, 实现点击切换路由
3.2 链接导航 - 高亮
目标: a标签和router-link区别就是, 路由组件激活时自带class
我们只需要声明具体class类名, 设置好具体的样式即可了
- router-link-exact-active (精确匹配) url中hash值, 与to属性值完全相同, 设置此类名
- router-link-active (模糊匹配) url中hash值, 包含to属性值, 设置此类名
3.3 自定义高亮类名
router-link上active-class属性,自定义高亮类名
- router-link上设置属性和类名
<router-link active-class="active" to="/home">首页</router-link>
- style中定义类名和具体样式
.active{
color: orange;
}
3.4 链接导航 - 跳转传参
目标: 在跳转路由时, 可以给路由的组件内传值
- 创建components/MyGoods.vue - 准备接收路由上传递的参数和值
<div>
你要浏览的商品是: {{ $route.query.name }} {{ $route.params.goodsname}}
</div>
- 路由定义
{
path: "/goods",
component: MyGoods
},
{
path: "/goods/:goodsname",
component: MyGoods
},
- 导航跳转, 传值给MyGoods.vue组件
<li><router-link to="/goods?name=外套">看外套</router-link></li>
<li><router-link to="/goods/裤子">看裤子</router-link></li>
总结: ?key=value 用刀了route.query.key 取值
/值 提前在路由规则/path/:key 用$route.params.key 取值
3.5 重定向和404
目标: 默认上来强制显示某个路由页面, 找不到路径给个提示页面
- 网页打开url默认hash值是空字符串或者/路径
- redirect是设置要重定向到哪里
- 路由最后, path匹配*(任意路径) – 前面不匹配就命中最后这个
- 在router/index.js - 修改配置
import NotFound from "@/components/NotFound";
const routes = [
{
path: "/",
redirect: "/home" // 重定向
},
// ...正常路由
{ // 当上面路由都不匹配, 匹配这个通配符, 显示NotFound页面
path: "*",
component: NotFound // 这里写404的页面
}
]
3.6 路由 - 模式设置
目标: 修改路由在地址栏的模式
router/index.js
const router = new VueRouter({
routes,
mode: "history" // 打包上线后需要后台支持, 模式是hash
})
hash路由例如: http://localhost:8081/#/home
history路由例如: http://localhost:8081/home
4. vue路由 - 编程式导航
4.1 基础使用
目标: 用JS代码跳转, 导航链接时用a标签
语法:
this.$router.push({
path: "路由路径", // 都去 router/index.js定义
name: "路由名"
})
- router/index.js - 给about路由配置name
{
path: "/about",
name: "about",
component: MyAbout
},
- App.vue - 换成按钮 配合js的编程式导航跳转
<template>
<div>
<h1>App组件</h1>
<div>
<button @click="homeFn">首页</button>
<button @click="movieFn">电影</button>
<button @click="aboutFn">关于</button>
</div>
<router-view></router-view>
</div>
</template>
<script>
export default {
methods: {
homeFn(){
this.$router.push("/home")
},
movieFn(){
this.$router.push({
path: "/movie"
})
},
aboutFn(){
this.$router.push({
name: "about"
})
}
}
};
</script>
4.2 跳转传参
目标: JS跳转路由, 传参
语法
this.$router.push({
name: "路由名字",
params: {
"key": 值
}
})
// 对应路由接收 $route.params.key 取值
// 第二种
this.$router.push({
path: "路由路径",
query: {
"key": 值
}
})
// 对应路由接收 $route.query.key 取值
router/index.js - 给/goods添加name属性
{
path: "/goods",
name: "thegoods",
component: MyGoods
},
App.vue
<template>
<div>
<h1>App组件</h1>
<div>
<button @click="waiFn">看外套</button>
<button @click="kuFn">看裤子</button>
</div>
<!-- <ul>
<li><router-link to="/goods?name=外套">看外套</router-link></li>
<li><router-link to="/goods/裤子">看裤子</router-link></li>
</ul> -->
<router-view></router-view>
</div>
</template>
<script>
export default {
methods: {
waiFn() {
this.$router.push({
path: "/goods",
query: {
name: "外套",
},
});
},
kuFn() {
this.$router.push({
name: "thegoods",
params: {
goodsname: "裤子",
},
});
},
},
};
</script>
总结:
path+query方式 -> 在url?传递
name+params方式 -> 在内存中传递(刷新就没了)
5. 嵌套和守卫
5.1 路由嵌套
目标: 在现有的一级路由下, 再嵌套二级路由
router-view嵌套架构图
- 创建需要用的所有组件
src/views/FindMusic.vue – 发现音乐页
src/views/MyMusic.vue – 我的音乐页
src/views/Child/Recommend.vue – 发现音乐页 / 推荐页面
src/views/Child/Ranking.vue – 发现音乐页 / 排行榜页面
src/views/Child/SongList.vue – 发现音乐页 / 歌单页面
- main.js - 专门转路由配置和导出路由对象
一级路由path从/开始定义
二级路由往后path直接写名字, 无需/开头
嵌套路由在上级路由的children数组里编写路由信息对象
import Vue from 'vue'
import VueRouter from 'vue-router'
import FindMusic from '@/views/FindMusic'
import MyMusic from '@/views/MyMusic'
// 二级路由
import Recommend from '@/views/Child/Recommend'
import Ranking from '@/views/Child/Ranking'
import SongList from '@/views/Child/SongList'
Vue.use(VueRouter)
const routes = [
{
path: "/",
redirect: "find"
},
{
path: "/find",
component: FindMusic,
// 1. 找准属于哪个一级路由下属的
// 2. 二级路由path无需加/
children: [
{
path: "recommend",
component: Recommend
},
{
path: "ranking",
component: Ranking
},
{
path: "songlist",
component: SongList
}
]
},
{
path: "/my",
component: MyMusic
}
];
const router = new VueRouter({
routes
})
export default router
- 说明
App.vue, 外层的router-view负责发现音乐和我的音乐页面切换
FindMusic.vue 内层的router-view负责发现音乐下的子tab对应的组件切换 - App.vue - 一级导航和路由展示
<template>
<div>
<div>
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
</div>
<div style="border: 1px solid orange">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {};
</script>
<style>
.router-link-active{
color: orange;
}
</style>
- FindMusic.vue - 设置二级导航和二级路由显示位置
<template>
<div>
<p>发现音乐 - 页面</p>
<div>
<router-link to="/find/recommend">推荐</router-link>
<router-link to="/find/ranking">排行榜</router-link>
<router-link to="/find/songlist">歌单</router-link>
</div>
<div style="border: 1px solid red; padding: 20px solid block;">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {};
</script>
<style>
</style>
5.2 高级用法 - 全局前置守卫
目标: 路由跳转之前, 会触发一个函数
使用例子: 在跳转路由前, 判断用户登陆了才能去<我的音乐>页面, 未登录弹窗提示回到发现音乐页面
- 在路由对象上使用固定方法beforeEach
// 路由前置守卫
router.beforeEach((to, from, next) => {
// to代表要跳转到哪个路径去, to的值是个对象可以打印看到
// from代表从哪个路径跳过去
console.log(to);
console.log(from);
// fullPath带?后面参数的, path是完整的路径
console.log("路由要跳转了");
// 模拟判断登录了没有, 登录后才能去我的音乐
let loginFlag = false; // 假设false代表未登录
if (to.path == "/my" && loginFlag == false) {
// 如果去个人中心页面, 判断未登录, 提示登录(并强制跳转回find)
alert("请先登录!");
next("/find");
} else {
// 如果不去/my页面就直接跳转
next();
}
});
5.3 高级用法 - 全局后置守卫
目标: 路由跳转后, 触发的函数
语法:
router.afterEach((to, from) => {})
router/index.js - 添加
router.afterEach((to, form) => {
console.log(to);
console.log(form);
console.log("路由发生了跳转");
})