vue核心技术与实战2
路由入门
单页应用程序
- 单页面应用(SPA):所有功能在一个html页面上实现
- 具体实例:网易云音乐
| 开发分类 | 实现方式 | 页面性能 | 开发效率 | 用户体验 | 学习成本 | 首屏加载 | ESO |
|---|---|---|---|---|---|---|---|
| 单页 | 一个html页面 | 按需更新性能高 | 高 | 非常好 | 高 | 慢 | 差 |
| 多页 | 多个html页面 | 整页更新性能低 | 中等 | 一般 | 中等 | 快 | 优 |
单页面应用:系统类网站/内部网站/文档类网站/移动端站点
多页面应用:公司官网/电商类官网
之所以开发效率高,性能高,用户体验好,最大的原因是页面按需更新,按需更新,首先需要明确的就是:访问路径和组件的对应关系,就需要学习路由
路由概念
生活中的路由:设备和ip之间的映射关系
vue中的路由:路径 和 组件 的映射关系
根据路由就能知道不同路径应该匹配渲染那个组件
VueRouter
目标:认识插件VueRouter,掌握VueRouter的基本使用步骤
作用:修改地址栏路径时,切换显示匹配的组件
说明:是Vue官方的一个路由插件,是一个第三方包
官网:官网链接
VueRouter的基本使用(5+2)
5个基础步骤(固定)
- 下载:下载VueRouter模块到当前工程,版本3.6.5
yarn add vue-router@3.6.5
- 引入
import VueRouter from 'vue-router'
- 安装注册
Vue.use(VueRouter)
-
创建路由对象
const router=new VueRouter() -
注入,将路由对象注入到new Vue实例中,建立关联
new Vue({ render:h =>h(App), router }).$mount('#app')
2个核心步骤
- 创建需要的组件(views目录),配置路由规则
import Vue from 'vue'
//路由的使用步骤 5+2
//1. 下载v3.6.5版本
//2.引入
//3. 安装注册 Vue.use
//4. 创建路由对象
//5. 注入到new Vue中,建立关联
//两个核心步骤
// 1. 建组件(view目录),配规则
// 2. 准备导航链接,配置路由出口(匹配的组件展示的位置)
import Find from '@/views/Find.vue'
import My from '@/views/My.vue'
import Friend from '@/views/Friend.vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter) //进行插件初始化
const router= new VueRouter({
//routes路由规则们
//route 一条路由规则{path:路径,component:组件}
routes:[
{path:'/find',component:Find},
{path:'/my',component:My},
{path:'/friend',component:Friend}
],
linkActiveClass: 'active',
linkExactActiveClass:'Eactive'
})
export default router
- 配置导航,配置路由出口(路径匹配的组件显示的位置)
<!-- 路由出口,匹配的组件所展示的位置 -->
<router-view></router-view>
组件存放目录问题
路由相关的组件,为什么放在views目录呢?
组件分类:.vue文件分为两类页面组件和复用组件
---注意都是vue组件(本质无区别)
分类开来更容易维护
- src/views文件夹
页面组件-页面展示-配合路由用
- src/components文件夹
复用组件-展示数据-常用于复用
路由进阶
路由模块封装
路由配置在main.js中不利于维护,所以将路由模块从main.js中抽离出来拆分模块,利于维护
以后如何快速引入组件? 基于 @ 指代 src 目录,从 src 目录出发找组件
声明式导航&导航高亮
需求:实现导航高亮效果
vue-router提供了一个全局组件router-link(取代a标签)
- 能跳转,配置to属性指定路径(必须配置),本质还是a标签,其一样的作用,to配置的路径不用加#键
- 能高亮,默认就会提供高亮类名,可以直接设置高亮样式(自带激活时的类名)
<div class="footer_wrap">
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/friend">朋友</router-link>
</div>
自带的类名写的样式
.footer_wrap a.active{
background-color: red;
}
两个类名-精确匹配&模糊匹配
说明:router-link的两个高亮类名太长了,我们希望能定制
如何自定义 router-link 的 两个高亮类名?
- linkActiveClass 模糊匹配 类名自定义
- linkExactActiveClass 精确匹配 类名自定
Vue.use(VueRouter) //进行插件初始化
const router= new VueRouter({
//routes路由规则们
//route 一条路由规则{path:路径,component:组件}
routes:[
{path:'/find',component:Find},
{path:'/my',component:My},
{path:'/friend',component:Friend}
],
linkActiveClass: 'active',
linkExactActiveClass:'Eactive'
})
声明式导航传参
目标:在跳转路由时,进行传值
- 查询参数传参
- 语法格式如下:
to="/path?参数名=值" - 对应页面组件接受传递过来的值:
$route.query.参数值
- 动态路由传参
- 配置动态路由
const router= new Vuerouter({
routes:[
...,
{
path:'/search/:words',
component:Search
}
]
})
- 配置导航链接
to="/path/参数值"
- 对应页面组件接收传递过来的值
$route.params.参数名
两种传参方式的区别:
动态路由参数可选符
配了路由path:"/search/words"按照下面步骤操作,不传参数时,会显示空白,所以/search/words表示,必须要穿参数,如果不传参数,也希望匹配,可以加个可选符”?“
路由重定向
问题:网页刚打开时,url默认是/路径,未匹配到组件时,会出现空白
说明:重定向-->匹配path后,强制跳转path路径
语法:{path:匹配路径,redirect:重定向到的路径}
// 创建了一个路由对象
const router = new VueRouter({
//一旦采用了history模式,地址栏就没有了#,需要后台配置访问规则
mode:'history',
routes: [
{ path :'/', redirect:'/Home' },
{ path: '/home', component: Home },
{ name:'search',path: '/search', component: Search },
{ path:'*', component:NotFound}
]
})
vue路由404
作用:当路径找不到匹配时,给提示页面
位置:配在路由最后
语法:path:" * "(任意路径)-前面不匹配就匹配最后这个
{ path:'*', component:NotFound}
Vue路由模式设置
问题:路由的路径看起来不自然,有#,能否切换成正常的路径形式?
- hash路由(默认) 例如:http://localhost:8080/#/home
- history路由(常用) 例如: http://localhost:8080/home (以后上线需要服务器端支持)
mode:'history',
编程式导航
问题:点击按钮跳转如何实现?
编程式导航:用js代码来进行跳转
1. 通过path路径的方式跳转
(1)【简写】
静态跳转传参
this.$router.push('路由路径?参数名=参数值')
动态路由传参
this.$router.push('/路由路径')
静态跳转传参
this.$router.push(`/search?key=${this.inpValue`) --
动态路由传参 this.router.push(`/search/${this.inpValue}`) --
(2)【完整写法】更适合传参
静态跳转传参
this.$router.push({
path:'路由路径'
query:{
参数名:参数值,
参数名:参数值
}
})
静态跳转传参示例:
this.$router.push({
path:'/search'
query:{
key:this.inpValue
}
})
动态路由传参示例:
this.$router.push({
path:`/search/${this.inputValue}`
})
*/
/*
2.通过命名路由的方式跳转(需要在index中给相应的路由路径起名字name:xxx)
然后使用
this.$router.push({
name:'起的名字'
query:{参数名:参数值},用query.key接收
params:{参数名:参数值},用params.words(words是自定义的)接收
示例:
this.$router.push({
name:'search',
params:{
word:this.inpValue
}
})
两种语法:
- path路径跳转(简易方便)
this.$router.push('路由路径')
this.$router.push({
path:'路由路径'
})
- name命名跳转(适合path路径长的场景)
this.$router.push({
name:'路由名'
})
{name:'路由名',path:'/path/xxx',component:xxx}
编程式导航传参
问题:点击搜索按钮:跳转需要传参如何实现?
两种传参方式:查询参数+动态路由传参
两种跳转方式:对于两种传参方式都支持
- path路径跳转传参
query传参
动态路由params传参
- name命名路由跳转传参 query传参
动态路由传参
总结:
通过命名路由的方式跳转(需要在index中给相应的路由路径起名字name:xxx)
然后使用
this.$router.push({
name:'起的名字'
query:{参数名:参数值},用query.key接收
params:{参数名:参数值},用params.words(words是自定义的)接收
})
例如:
this.$router.push({
name:'search',
params:{
word:this.inpValue
}
})
综合案例:面经基础版
案例分析:
- 配路由
- 首页和面经详情,两个一级路由(首页显示-一级路由)
- 内嵌四个可切换页面(点击切换-二级路由)
- 实现功能
- 首页请求渲染
- 跳转传参到详情页,详情页渲染
- 组件缓存,优化性能
二级路由
const router = new VueRouter({
routes: [//一级路由
{
path:'/',
component:Layout,
redirect:'/article',
children:[//二级路由
{
path:'/article',
component:Article
},
{
path:'/collect',
component:Collect
},
{
path:'/like',
component:Like
},
{
path:'/user',
component:User
}
]
},
{//一级路由
path:'/detail/:id',
component:ArticleDetail
}
]
})
导航高亮
导航内容,二级路由出口,首页内容细节都在首页Layout
<template>
<div class="h5-wrapper">
<div class="content">
<!-- 二级路由出口 -->
<router-view>
</router-view>
</div>
<nav class="tabbar">
<!-- 导航高亮
1.将a标签替换成routerlink(to)
2.结合高亮类名实现高亮效果
-->
<router-link to="/article">面经</router-link>
<router-link to="/collect">收藏</router-link>
<router-link to="/like">喜欢</router-link>
<router-link to="/user">我的</router-link>
</nav>
</div>
</template>
<script>
export default {
//组件名(如果没有配置name,才会找文件名作为组件名)
name: 'LayoutPage',
activated (){
alert('你好,欢迎回到首页')
}
}
</script>
//导航高亮样式
a.router-link-active{
color: orangered;
}
请求渲染
路由开始跳转时发送请求,渲染页面
<span @click="$router.back()" class="back"><</span>返回上一页
<template>
<div class="article-page">
<div
v-for="item in articles" :key="item.id"
@click="$router.push(`/detail/${item.id}`)"
class="article-item">
<div class="head">
<img :src=item.creatorAvatar alt="" />
<div class="con">
<p class="title">{{item.stem}}</p>
<p class="other">{{item.creatorName}} | {{item.createdAt}}</p>
</div>
</div>
<div class="body">
{{ item.content }}
</div>
<div class="foot">点赞 {{item.likeCount}} | 浏览 {{item.views}}</div>
</div>
</div>
</template>
<script>
//首页请求渲染
//1. 安装axios
//2. 看接口文档,确认请求方式,请求地址,请求参数
// 请求地址:https://mock.boxuegu.com/mock/3083/articles
// 请求方式:get
//3. created中发请求,获取数据,存起来
//4. 页面动态渲染
//跳转详情页传参
//1. 查询参数传参 (适合多个参数传参)
// ?参数=参数值 =>this.$route.query.参数名
//2. 动态路由传参 (单个参数传参更优雅方便)
// 改造路由 =>/路径/:参数 => this.$route.params.参数名
// (1). 访问/重定向到/article(redirect)
// (2). 返回上一页 =>添加点击事件$router.back()
import axios from 'axios'
export default {
name: 'ArticlePage',
data(){
return{
articles:[]
}
},
async created(){
const res=await axios.get('https://mock.boxuegu.com/mock/3083/articles')
// console.log(res)
this.articles=res.data.result.rows
}
};
</script>
路由传参
复习路由跳转传参知识
//跳转详情页传参
//1. 查询参数传参 (适合多个参数传参)
// ?参数=参数值 =>this.$route.query.参数名
//2. 动态路由传参 (单个参数传参更优雅方便)
// 改造路由 =>/路径/:参数 => this.$route.params.参数名
// (1). 访问/重定向到/article(redirect)
// (2). 返回上一页 =>添加点击事件$router.back()
动态路由传参
@click="$router.push(’/detail/${item.id}‘)"动态路由传参
接收参数,使用其信息发送请求
async created(){
console.log(this.$route.params.id)
const id=this.$route.params.id
const {data}=await axios.get(`https://mock.boxuegu.com/mock/3083/articles/${id}`)
console.log(data)
this.articlemsg=data.result
}
路由配置
{
path:'/detail/:id',
component:ArticleDetail
}
组件缓存Keep-alive
问题:从面经 点到 详情页,返回的时候发现数据被重新加载了,如果希望回到原来的位置,就需要缓存特定的组件
原因:路由跳转后,组件被销毁了,返回回来之后组件又被重建了,所以数据被重新加载了
解决:利用keep-alive将组件缓存下来
- keep-alive是什么?
keep-alive是Vue的内置组件,当他包裹动态组件时,会缓存不活动的组件实例,而不是销毁他们。keep-alive是一个抽象组件,它自身不会渲染成一个DOM元素,也不会出现在父组件链中
- keep-alive的优点
在组件切换过程中,把切换出去的组件保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性
- keep-alive的三个属性
include:组件名数组,只有匹配的组件会被缓存
exclude:组件名数组,任何匹配的组件都不会被缓存
max:最多可以缓存多少组件实例
- keep-alive的使用会触发两个生命周期函数
//页面激活--进入页面时执行的函数
activated (){
alert('你好,欢迎回到首页')
}
<!-- 包裹了keep-alive以及路由匹配的组件都会被缓存
layout组件(被缓存)多两个生命周期钩子
--active 激活时,组件被看到时触发
--deactived 失活时,离开页面组件看不见时触发
articleDetailPage组件(未被缓存)
需求:只希望Layout被缓存,incloude配置
:include=“组件名数组”-->
<keep-alive :include="keepArr">
<router-view></router-view>
</keep-alive>
<script>
export default {
name: 'h5-wrapper',
data(){
return{
//缓存组件名的数组
keepArr:['LayoutPage']
}
},
}
</script>