Vue学习
Vue 06 Vue Router
生活中的路由器:路由器的每一个网线接口,都会对应一个设备
多个路由得由一个路由器进行管理
01 引入
路由就是一组 key-vaule 的对应关系
多个路由,需要经过路由器的管理
编程里的路由,为了实现 SPA (single page web application)
02 概念
Vue-router
vue的一个插件库,专门用来实现SPA应用
SPA
对SPA应用的理解:
1、单页Web应用(single page web application,SPA)
2、整个应用只有一个完整的页面。 index.html
3、点击页面中的导航链接不会刷新页面,只会做页面的局部更新
4、数据需要通过ajax请求获取。
注:Ajax 技术,在不刷新整个页面的情况下更新网页内容。
路由
什么是路由?
- 一个路由就是一组映射关系
- key为路径,value可能是 function 或者 component
路由分类
-
后端路由
① 理解:value是function,用于处理客户端提交的请求
② 工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据。
-
前端路由
① 理解: value是component,用于展示页面内容
② 工作过程:当浏览器的路径改变时,对应的组件就会显示
03 基本路由
- 安装 vue-router:
npm i vue-router
2022年2月7日之后,vue-router的默认版本为4版本,vue-router4只能在vue3中使用,vue-router3只能在vue2中使用。因为当前教学视频使用的是vue2,所以在下载vue-router的时候要特地知名版本。npm i vue-router@3
vue-router是一个插件库,所以要用 vue.use使用
- 引入、使用 vue-router
在 src 下 新建一个 文件夹 router 和 index.js 文件
import VueRouter from 'vue-router'
引入之后,VueRouter当作构造函数使用
- 具体文件
src/router/index.js
// 该文件专门用于创建整个应用的路由器
// 【引入VueRouter】要使用VueRouter就要先引入,VueRouter是一个构造函数
import VueRouter from 'vue-router'
// 【使用VueRouter】
import Vue from 'vue'
Vue.use(VueRouter)
// 【引入组件】(因为配置路由要指定组件)
import About from '../components/MyAbout.vue'
import Home from '../components/MyHome.vue'
// 创建并暴露一个路由器
export default new VueRouter({
routes: [
// 每一个配置对象都是一个路由
{
path: '/about',
component: About
},
{
path: '/home',
component: Home
}
]
})
main.js
import Vue from 'vue'
import App from './App.vue'
// 关闭vue的生产提示
Vue.config.productionTip = false
// 引入路由
import router from './router/index'
new Vue({
el: '#app',
render: h => h(App),
router // 让 vm 和每个vc都可以使用路由
})
App.vue
<router-view></router-view>
指定组件的呈现位置
原始HTML中我们使用a标签实现页面的跳转(但是页面会刷新),这里使用<router-link></router-link>
,其中 to 属性指定跳转的路由,如to=“/about” ;属性 active-class="active"指定点击之后谁会被加上active类
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header"><h2>Vue Router Demo</h2></div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- 原始HTML中我们使用a标签实现页面的跳转(但是页面会刷新 -->
<!-- <a class="list-group-item active" href="./about.html">About</a>
<a class="list-group-item" href="./home.html">Home</a> -->
<!-- 最终在页面中转换为a标签 -->
<router-link class="list-group-item" active-class="active" to="/about">About</router-link>
<router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
</div>
</div>
<div class="col-xs-6">
<div class="panel">
<div class="panel-body">
<!-- 指定组件的呈现位置 -->
<router-view></router-view>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
使用总结
1、安装vue-router,命令 npm i vue-router
2、引入import VueRouter from ‘vue-router’
应用插件 Vue.use(VueRouter)
3、编写router配置项: src/router/index.js中配置
4、实现切换(active-class可以配置高亮样式)
<router-link class="list-group-item" active-class="active" to="/about">About</router-link>
5、指定展示位置
<router-view></router-view>
注意事项
1、一般把路由组件放在 pages 文件夹里面。一般组件放在 components 文件夹里面
2、通过切换,“隐藏"了的路由组件,默认是被销毁掉的,需要的时候再去挂载。可以在组件里面用生命周期函数 mounted、beforeDestroy验证
3、每个组件都有自己的$route属性,里面存储着自己的路由信息
4、整个应用只有一个router,可以通过组件的$router属性获取到
04 嵌套(多级)路由
1、配置路由规则,使用children配置项
二级路由的path里不可以写斜杠(/)
// 【引入组件】(因为配置路由要指定组件)
import About from '../pages/MyAbout.vue'
import Home from '../pages/MyHome.vue'
// 二级路由
import News from '../pages/MyNews.vue'
import Message from '../pages/MyMessage.vue'
// 创建并暴露一个路由器
export default new VueRouter({
routes: [
// 每一个配置对象都是一个路由
{
path: '/about',
component: About
},
{
path: '/home',
component: Home,
children: [
{
path: 'news', // 【注意】这里不可以写斜杆
component: News
},
{
path: 'message',
component: Message
}
]
}
]
})
2、跳转(要写完整路径)
<router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
05 路由传参
query参数
- 跳转路由并携带query参数,to的字符串写法
<router-link :to="`/home/message/detail?id=${item.id}&title=${item.name}`">{{item.name}}</router-link>
这里 to前面一定要写冒号,表示绑定,是双引号里面的值。然后双引号里面写单引号,:to表示 ``绑定了反引号的字符串,再用模板字符串进行编写。
- 跳转路由并携带query参数,to的对象写法
<router-link :to="{
path:'/home/message/detail' ,
query: {
id: item.id,
name: item.name
}
}">
{{item.name}}
</router-link>
-
在 下面的组件中
this. r o u t e . q u e r y . i d 和 t h i s . route.query.id 和 this. route.query.id和this.route.query.name 就可以访问到
params参数
写法一、跳转路由并携带params参数,to的字符串写法
- Message.vue
<router-link :to="`/home/message/detail/666/你好啊`">{{item.name}}</router-link>
或者
<router-link :to="`/home/message/detail/${id}/${title}`">{{item.name}}</router-link>
- router/index.js 占位符【必须要写】
{
path: 'message',
component: Message,
children: [
{
name: 'xiangqing',
path: 'detail/:id/:title', // 占位符
component: Detail
}
]
}
- Detail.vue
$this.route.params
<template>
<ul>
<li>消息编号:{{$route.params.id}}</li>
<li>消息标题:{{$route.params.title}}</li>
</ul>
</template>
写法二、跳转路由并携带params参数,to的对象写法(必须使用命名路由)
注意:也需要去 router/index.js 中使用占位符
<router-link :to="{
name: 'xiangqing', // 命名路由
params: {
id: item.id,
titlie: item.title
}
}">
{{item.title}}
</router-link>
路由的props配置
作用:让路由组件更方便收到参数
如上图,当点击 message001 message002 message003的时候,想要下面的部分切换数据显示。此时只需要一个detail组件,和query参数、params参数一样,目的都是想向detail传递参数
第一种写法:
<template>
<ul>
<li>消息编号:{{$route.params.id}}</li>
<li>消息标题:{{$route.params.title}}</li>
<h3>{{a}}</h3>
<h3>{{b}}</h3>
</ul>
</template>
<script>
export default {
name: 'MyDetail',
props: ['a', 'b'], // 接收
mounted() {
console.log(this.$route);
}
}
</script>
第二种写法:
若布尔值为真,就会把该路由组件收到的所有params参数以props的形式传递给Detail
第三种写法:
06 命名路由
作用:可以简化路由的跳转
使用:
① 给路由命名
② 简化跳转
07 router-link
作用:控制路由跳转时操作浏览器历史记录的模式
浏览器的历史记录有两种写入方式:① push追加历史记录(栈),② replace是替换当前记录。router-link默认是push模式,可以开启replace模式
<router-link :replace="true" :to="`/home/message/detail/666/你好啊`">{{item.name}}</router-link>
也可以简写replace
<router-link replace :to="`/home/message/detail/666/你好啊`">{{item.name}}</router-link>
08 编程式路由导航
作用:不借助 <router-link>
实现路由跳转,让路由跳转更加灵活
具体编码:
this.$router.push({
name: 'xiangqing',
params: {
id: item.id,
title: item.title
}
})
this.$router.replace({
name: 'xiangqing',
params: {
id: item.id,
title: item.title
}
})
// 后退
this.$router.back()
// 前进
this.$router.forward()
// 正数往前进3步,负数往后退
this.$router.go(3)
09 缓存路由组件
作用:让不展示的路由组件保持挂载,不被销毁。
引入
注意,MyNew组件是在MyHome组件中展示的,所以要去 MyHome.vue 文件写代码实现。具体实现如下:
-
如果没有 include,就表示 router-view 里面展示的所有组件都被缓存。
-
一定要写组件名
-
或者用数组形式:
<keep-alive :include="['MyNews','MyMessage']">
<router-view></router-view>
</keep-alive>
10 两个新的生命周期
-
作用:路由组件独有的两个钩子,用于捕获路由组件的激活状态。
-
具体名字:
① activated 路由组件被激活时触发
② deactivated 路由组件被激活时触发
-
activated、deactivated、(nextTick)这三个生命周期函数没有在之前的生命周期图上显示。
11 路由守卫
Navigation Guards :保护路由的安全。(权限)
1全局路由守卫
① 全局前置路由
需求:只有当学校为尚硅谷,才能查看 news和,message中的内容
这里为了演示,我们提前在localStorage中存储了 school:‘atguigu’
- router/index.js
const router = new VueRouter({
routes: [...] })
// 【全局前置路由守卫】
// beforeEach 在每一次路由切换之前、初始化时调用
// to去哪 from从哪来
router.beforeEach((to,from,next)=>{
// 这里也可以使用 to.name 做判断
if(to.path === '/home/news' || to.path === '/home/message') {
if(localStorage.getItem('school') === 'atguigu') {
next()// 放行
} else{
alert('学校名不对,无权限')
}
} else {
next()
}
})
export default router
② 全局后置路由
这里补充一个meta配置(路由元信息),里面可以自定义数据
- 以全局前置路由为例
router.beforeEach((to,from,next)=>{
if(to.meta.isAuth) {
//如果需要鉴别权限
if(localStorage.getItem('school') === 'atguigu') {
next()// 放行
} else{
alert('学校名不对,无权限')
}
} else {
next()
}
})
- 全局后置路由
对比前置路由,他的参数没有next
router.afterEach((to,from)=>{
})
使用场景:跳转页面(路由)之后,修改document.title
2独享守卫
router/index.js
beforeEnter
3组件内守卫
beforeRouteEnter、beforeRouteLeave
总结路由守卫
作用:对路由进行权限控制
分类:全局守卫、独享守卫、组件内守卫
12 hash模式与history模式
路由器两种工作模式 :hash模式与history模式
注:本小节提到的哈希与数据加密无关,只是站在前端人员的角度去分析路径
注意:# 包括 # 后面的都算作路径里面的 hash值
特点是不会随着 http请求发给服务器。
路由器工作模式:hash模式、history模式
默认是hash
hash的兼容性好。
项目上线流程:
**把前端所有写的东西打包,**就是生成最纯粹的.html .css .js。怎么把我们的.vue转成这些呢?就需要借助命令。
之前我们使用 npm run serve,开了一个8080的服务器。但是当项目写完之后就应该使用命令 npm run build
npm run build。生成一个dist文件夹
这里只有一个index.html是因为我们学的就是单页面文件。
打包之后的文件需要在服务器上部署,直接双击打开是看不了的
接下来,老师使用node.js加上express框架搭建一个微型服务器,把dist部署上去
如果使用history模式,虽然路径美观,但是在请求的时候,会把hash模式下原本#后面不算做资源路径的东西,算作请求,可是后端没有这些资源,于是会报404错误。
解决方法是在后端中,node.js中一个专门的中间件 connect-history-api-fallback
总结
路由器两种工作模式 :hash模式与history模式
1、对于一个url来说,什么是hash值?——#及其后面的内容就是hash值。
2、hash值不会包含在HTTP请求中,即: hash值不会带给服务器。
3、hash模式
① 地址中永远带着#号,不美观。
② 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
③ 兼容性较好。
4、history模式
① 地址干净,美观
② 兼容性和hash模式相比略差
③ 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题
Vue 07 Vue UI组件库
移动端常用UI组件库:Vant、 Cube UI、 Mint UI
PC端常用UI组件库:Element UI、IView UI
注意要学习按需引入