今日学习目标
- 能够了解单页面应用概念和优缺点
- 能够掌握vue-router路由系统使用
- 能够掌握链接导航和编程式导航用法
- 能够掌握路由嵌套和路由守卫
- 能够掌握vant组件库基础使用
一、vue路由-简介和基础使用
1、什么是路由
思考
-
- 路由是什么呢?
- Vue中的路由是什么?
目标
设备和ip的映射关系
目标
接口和服务的映射关系
目标
路径和组件的映射关系
小结
-
- 路由是什么呢?
路由是一种映射关系 - Vue中的路由是什么?
路径和组件的映射关系
- 路由是什么呢?
2、为什么使用路由
思考
-
- 什么是单页面应用?
- 单页面应用好处?
- 单页面如何切换场景?
目标
在一个页面里, 切换业务场景
具体使用示例: 网易云音乐 网易云音乐
单页面应用(SPA): 所有功能在一个html页面上实现
前端路由作用: 实现业务场景切换
优点:
- 整体不刷新页面,用户体验更好
- 数据传递容易, 开发效率高
缺点:
- 开发成本高(需要学习专门知识)
- 首次加载会比较慢一点。不利于seo
小结
1、什么是单页面应用?
所有的业务都在一个页面编写, 只有一个html
2、单页面应用好处?
开发效率高, 用户体验好
3、单页面如何切换场景?
依赖路由切换显示
3、vue-router介绍
思考
以后Vue中如何实现路由?
目标
如何在Vue项目中集成路由
使用
官网: Vue Router
vue-router模块包
它和 Vue.js 深度集成
可以定义 - 视图表(映射规则)
模块化的
提供2个内置全局组件
声明式导航自动激活的 CSS class 的链接
……
小结
1、以后Vue中如何实现路由?
集成vue-router模块包
2、注意:vue现在所有的依赖包默认都是V3版本相匹配的,所以vue-router要手动指定版本(3.*.*)下载
4、路由 - 组件分类
思考
-
- 为何把.vue文件分类?
- 页面组件用在哪里?
- 复用组件用在哪里?
目标
.vue文件分2类, 一个是页面组件, 一个是复用组件
.vue文件本质无区别, 方便大家学习和理解, 总结的一个经验
src/views(或pages) 文件夹 和 src/components文件夹
- 页面组件 - 页面展示 - 配合路由用
- 复用组件 - 展示数据/常用于复用
小结
views下的页面组件, 配合路由切换, components下的一般引入到views下的vue中复用展示数据
-
- 为何把.vue文件分类?
方便理解和使用 - 页面组件用在哪里?
配合路由, 切换页面 - 复用组件用在哪里?
页面组件, 重复渲染结构一样的标签
- 为何把.vue文件分类?
5、vue-router使用
思考
-
- vue-router本质是什么?
- vue-router如何使用?
- 规则如何生效?
目标
学会vue官方提供的vue-router路由系统功能模块使用
分析
-
-
-
- 下载vue-router模块到当前工程
- 在main.js中引入VueRouter函数
- 添加到Vue.use()身上 – 注册全局RouterLink和RouterView组件
- 创建路由规则数组 – 路径和组件名对应关系
- 用规则生成路由对象
- 把路由对象注入到new Vue实例中
- 用router-view作为挂载点, 切换不同的路由页面
-
-
代码
<template>
<div>
<div class="footer_wrap">
<a href="#/find">发现音乐</a>
<a href="#/my">我的音乐</a>
<a href="#/part">朋友</a>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {};
</script>
<style scoped>
.footer_wrap {
position: fixed;
left: 0;
top: 0;
display: flex;
width: 100%;
text-align: center;
background-color: #333;
color: #ccc;
}
.footer_wrap a {
flex: 1;
text-decoration: none;
padding: 20px 0;
line-height: 20px;
background-color: #333;
color: #ccc;
border: 1px solid black;
}
.footer_wrap a:hover {
background-color: #555;
}
.top {
padding-top: 62px;
}
</style>
main.js代码
import Vue from 'vue'
import App from './App.vue'
import Find from '@/views/Find.vue'
import My from '@/views/My.vue'
import Part from '@/views/Part.vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: "/find",
component:Find
},
{
path: "/my",
component:My
//component值不能加引号,后面是变量引进需要的组件
},
{
path: "/part",
component:Part
}
]
const router = new VueRouter({
routes
//属性名就是routes,是固定写法,如果前面声明的变量不是routes,不能简写
})
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App),
}).$mount('#app')
vue路由 - 声明式导航
1.声明式导航基础实用
如何实现导航高亮效果?
vue-router提供的全局组件router-link
1.自带高亮类名
2.可以不用写点击事件
3.实际上还会渲染成a标签
本质:router-link是vue-router自带的全局组件,无需注册,可以用router-link来替代a标签
to属性替代herf属性
浏览器会显示渲染成a标签,to属性转换成herf属性,但是自带类名,点击谁类名会切换到谁的身上,实现高亮
<div>
<div class="footer_wrap">
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part">朋友</router-link>
</div>
2、声明式导航 - 跳转传参
目标
在跳转路由时, 可以给路由对应的组件内传值
2种方案
1.
to="/path?参数名=值”
在需要显示的页面接收:
$route.query.参数名
2.动态路由:
to="/path/值
,需要路由对象提前配置,在路由path路径上配置
(有“:”的路径代表要接受具体的值:)
提前配置的参数名需要和接收的参数名保持一致
接收:
$route.params.参数名
三、vue路由 - 重定向和模式
目标
网页打开有默认路径,匹配path后,强制跳转path路径,
方法
redirect:“/find”
值为强制切换路由路径
2、404页面
思考
- 当你访问不存在的页面会显示什么?
- 当我们访问的路由路径不存在应该怎么办?
目标
如果路由hash值, 没有和数组里规则匹配,默认给一个404页面
方法
1.创建一个notfound页面
2.引入文件
3.当访问不存在的页面,path匹配(任意路径“*”),匹配任意路径后router会自动遍历规则数组--前面不匹配就命中后面这个
注意
404代码在main.js中一定要放到最后(规则是从前往后逐个比较)
代码
创建NotFound页面
<template>
<img src="../assets/404.png" alt="">
</template>
<script>
export default {
}
</script>
<style scoped>
img{
width: 100%;
}
</style>
引入main.js
import NotFound from '@/views/NotFound'
放到数组最后
path: "*",
component: NotFound
3、模式设置
如何切换路由模式呢?
目标:
修改路由在地址栏的模式
默认的是哈希字符串
方法:
history路由:(线上需要服务器端支持,否则找的是文件夹)
代码:
const router = new VueRouter({
routes,
mode: "history"
// 不写默认的是哈希字符串
})
四、vue路由 - 编程式导航
a标签可以切换路由路径, 用JS方式可以切换吗
1、vue路由-编程式导航
目标:
用js代码进行跳转
语法:
path或者name任选一个
name方法需要在main.js中添加name属性
this.$router.push({path:"路由路径"})
this.$router.push({name:"路由名"})
注意:
用name跳转浏览器url,跳转的hash值也会转换成路由路径
name命名不能重复
使用场景:
1.使用name方便修改,在页面看不到可以随便定义
2.path可以在url的Hash值看到
代码:
main.js数组中给路由起名字
{
path: "/find",
name: "Find",
component: Find
},
{
path: "/my",
name: "My",
component: My
},
{
path: "/part",
name: "Part",
component: Part
},
<template>
<div>
<div class="footer_wrap">
<span @click="btn('/find', 'Find')">发现音乐</span>
<span @click="btn('/my', 'My')">我的音乐</span>
<span @click="btn('/part', 'Part')">朋友</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
记得在页面添加js函数
<script>
export default {
methods: {
btn(pt, na) {
this.$router.push({
path: pt,
name: na,
});
},
},
};
</script>
不经常变换Dom的一半运用声明式导航,
接口请求需要跳转的页面常运用编程时导航
2、编程式导航 - 跳转传参
JS切换路由, 能否传值给路由页面?
目标:
JS跳转路由, 传参
语法:
query / params 任选 一个
this.$router.push({
path: "路由路径"
name: "路由名",
query: {
"参数名": 值
}
params: {
"参数名": 值
}
})
// 对应路由接收 $route.params.参数名 取值
// 对应路由接收 $route.query.参数名 取值
推荐name和query 一起用
注意:
利用path进行跳转是,只能用query来接,path不能和params一起用,path会自动忽略params
冗余导航:连续点击同意url会爆出冗余导航错误
代码:
<span @click="oneBtn">朋友--小船</span>
<span @click="twoBtn">朋友--小智</span>
oneBtn() {
this.$router.push({
name: "Part",
params: {
username: "小船",
},
});
},
twoBtn() {
this.$router.push({
name: "Part",
query: {
name: "小智",
},
});
},
<template>
<div>
<p>我的收藏</p>
<p>我的历史记录</p>
<p>人名:{{ $route.query.name }}--{{ $route.params.username }}</p>
</div>
</template>
五、vue路由 - 嵌套和守卫
1、vue路由 - 路由嵌套
某路由页面, 可否再套入一套路由系统?
目标:
在现有的一级路由下, 再嵌套二级路由
路由嵌套是嵌套在上一级页面里面
方法:
1.,创建所需组件,创建新的Second文件夹(方便寻找)创建3个文件
2.找到需要的一级路径,在其配置2级路由器路径children,直接写名字,无需/开头
代码
配置find.vue一级文件
<template>
<div>
<router-link to="/find/recommend">每日推荐</router-link>
<div></div>
<router-link to="/find/songsheet">排行榜</router-link>
<div></div>
<router-link to="/find/RankingList">我的歌单</router-link>
<div style="1px solid red;">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {};
</script>
<style scoped>
.nav_main {
background-color: red;
color: white;
padding: 10px 0;
}
.nav_main a {
text-align: center;
text-decoration: none;
color: white;
font-size: 12px;
margin: 7px 17px 0;
padding: 0px 15px 2px 15px;
height: 20px;
display: inline-block;
line-height: 20px;
border-radius: 20px;
}
.nav_main a:hover {
background-color: brown;
}
.nav_main .router-link-active {
background-color: brown;
}
</style>
配置二级文件
不要忘记引进
效果
不会影响其他页面正常切换
2、声明导航 - 类名区别
router-link激活的2个类名有什么区别呢?
目标:
声明式导航-激活类名区别
1.router-link-exact-active (精确匹配) url中hash值路径, 与href属性值完全相同, 设置此类名
2.router-link-active (模糊匹配) url中hash值, 包含href属性值这个路径
3、全局前置守卫
如何给路由添加一个权限判断?
目标
路由跳转之前, 先执行一次前置守卫函数, 判断是否可以正常跳转
场景:
当你要对路由权限进行判断
语法:
必须调用next()才会正常跳转
router.berforeEach((to,from,next) => {//路由跳转之前先实行,在判定是否跳转})
参数代表:
参数一:要跳转到的路由(路由对象信息)
参数二:是从哪里跳转的(路由对象信息)
参数三:函数体-next()正常跳转,next(false)原地停留,next(强制修改到龄一路由路径)
// 目标: 路由守卫
// 场景: 当你要对路由权限判断时
// 语法: 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() // 正常放行
}
})