面经基础版案例(路由,请求渲染,传参,组件缓存)
1.案例效果分析
2.配置一级路由(首页,详情)
把首页配成一个路由 → 注意项
关于'/'
import Vue from 'vue'
import VueRouter from "vue-router";
import Layout from '@/views/Layout'
import ArticleDetail from '@/views/ArticleDetail'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{
path:'/',//首页可以配成一个/
component: Layout //渲染一个组件
},
{
path:'/detail',
component:ArticleDetail
}
]
})
export default router
3.配置二级路由
如果要配嵌套路由可以直接写一个配置项
children
import Vue from 'vue'
import VueRouter from "vue-router";
import Layout from '@/views/Layout'
import Article from '@/views/Article'
import Collect from '@/views/Collect'
import Like from '@/views/Like'
import User from '@/views/User'
import ArticleDetail from '@/views/ArticleDetail'
Vue.use(VueRouter)
const router = new VueRouter({
// 如果访问到 /artucle这个路径时,就匹配展示Article组件
routes: [
{
path:'/',//首页可以配成一个/
component: Layout, //渲染一个组件
//通过 children 配置项,可以配置嵌套子路由
//配置嵌套子路由分成两步
//1.在children配置项中配置规则
//2.准备二级路由出口
children:[
{
path:'/article',
component:Article
},
{
path:'/collect',
component:Collect
},
{
path:'/like',
component:Like
},
{
path:'/user',
component:User
},
]
},
{
path:'/detail',
component:ArticleDetail
}
]
})
export default router
下面是首页二级路由出口
<template>
<div class="h5-wrapper">
<div class="content">
<!-- 不希望写死,也要换成路由组件,二级路由出口 ,就会展示匹配到的二级路由组件 -->
<router-view></router-view>
</div>
</template>
4.导航高亮效果
1.将a标签换成router-link
,要加to属性
2.结合高亮类名,实现高亮效果(router-link-active模糊匹配)
layout.vue
<template>
<div class="h5-wrapper">
<div class="content">
<!-- 不希望写死,也要换成路由组件,二级路由出口 ,就会展示匹配到的二级路由组件 -->
<router-view></router-view>
</div>
<nav class="tabbar">
<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>
<style>
a.router-link-active{
color: palevioletred;
}
</style>
5.首页的请求渲染
首页的请求渲染其实指的是嵌套二级路由中的面经里面的文章列表,就是组件Article.vue
Article.vue
<template>
<div class="article-page">
<div
v-for="item in articles"
:key="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>
import axios from 'axios';
//首页请求渲染
//1.用axios请求,安装axios
//2.看对应的接口文档,确认请求方式和地址和参数
// 请求地址: https://mock.boxuegu.com/mock/3083/articles
// 请求方式: get
//3.具体的确认完了,在created中发请求,获取数据,然后存起来
//4.页面动态渲染
export default {
name: 'ArticlePage',
async created () {
const res = await axios.get('https://mock.boxuegu.com/mock/3083/articles')
this.articles = res.data.result.rows
},
data () {
return {
articles:[
]//把拿到的数据存到里面
}
}
}
</script>
6.传参(查询参数 $ 动态路由)
- 先给文章注册点击事件
- 有两种传参方式:
第一种:查询参数传参 ?参数=参数 通过 this.$route.query.参数名 获取(更适合多个参数的情况)
@click="$router.push(`/detail?id=$(item.id)`)"
可以在ArticlDetail.vue中获取一下👇
第二种:动态路由传参 改造路由 => /路径/参数 通过 this.$route.params.参数(单个参数更优雅方便)
- 改路由 把path:‘/detail’改成path:’/detail/:id’
- 把标蓝的值改成
${item.id}
(通过这个来跳转)
- 在ArticleDetail接收(不是通过
query
,而是通过$route.params
)
- 解决bug
返回首页一片空白
可以在index.js中给首页进行重定向
点击返回按钮返回首页,只要写一个back就可以了
<nav class="nav"><span @click="$router.back()" class="back"><</span> 面经详情</nav>
7.详情页渲染
先看接口文档,然后在created当中去发请求,发完请求之后将数据存储到article中,最后在页面中渲染。问题是当article内容没有获取完成,就不用做渲染
<template>
<div class="article-detail-page" v-if="article.id"><!--应为加载需要事件,所以加载的时候,有一段时间会不显示数据,
只显示“浏览量”这几个字等,所以可以写一个v-if,告诉它什么时候才做渲染-->
<nav class="nav"><span @click="$router.back()" class="back"><</span> 面经详情</nav>
<header class="header">
<h1>{{ article.stem }}</h1>
<p>{{ article.createdAt }} | {{ article.views }} 浏览量 | {{ article.likeCount }} 点赞数</p>
<p>
<img
:src="article.creatorAvatar"
alt=""
/>
<span>{{ article.creatorName }}</span>
</p>
</header>
<main class="body">
{{ article.content }}
</main>
</div>
</template>
<script>
import axios from 'axios';
// 请求地址: https://mock.boxuegu.com/mock/3083/articles/:id
// 请求方式: get
export default {
name: "ArticleDetailPage",
data() {
return {
article:{}//存数据
}
},
async created () {
const id = this.$route.params.id
const { data } = await axios.get(`https://mock.boxuegu.com/mock/3083/articles/${id}`)//id不能写死
this.article = data.result
console.log(this.article)
},
}
</script>
8.组件缓存kepp-alive
问题:从面经 点到 详情页,又点返回,数据重新加载了 → 希望回到原来的位置
原因:路由跳转后,组件被销毁了,返回回来组件又被重建了,所以数据重新被加载了
解决:利用keep-alive将组件缓存下来
keep-alive是什么
- keep-alive 是Vue的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
- keep-alive 是一个抽象组件:它自身不会渲染成一个DOM元素,也不会出现在父组件链中。
keep-alive的有点
- 在组件切换过程中 把切换出去的组件保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。
<template>
<div class="h5-wrapper">
<!-- 包裹了keep-alive 一级路由匹配的组件都会被缓存
Layout组件 Detail组件,都会被缓存
-->
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
</template>
问题是,直接用它包裹,会缓存所有被切换的组件,以后不论首页点什么,都是跳转回来之前的那一页
3. keep-alive的三个属性
①include:组件名数组,只有匹配的组件会被缓存
App.vue
<template>
<div class="h5-wrapper" :include="['LayoutPage']">
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
</template>
Layout.vue
<script>
export default {
//组件名,如果没有配置name,才会找文件名作为组件名
name: "LayoutPage",
}
</script>
也可以这么写,如果将来要缓存的组件多的话
<template>
<div class="h5-wrapper">
<!-- 包裹了keep-alive 一级路由匹配的组件都会被缓存
Layout组件 Detail组件,都会被缓存
需求:只希望Layout被缓存,include配置
:include="组件名数组"
-->
<keep-alive :include="['keepArr']">
<router-view></router-view>
</keep-alive>
</div>
</template>
<script>
export default {
name: "h5-wrapper",
//如果缓存的组件比较多,可以提供一个数据
data () {
return {
//缓存组件名的数组
keepArr:['LayoutPage']
}
}
}
</script>
②exclude:组件名数组,任何匹配的组件都不会被缓存
③max:最多可以缓存多少组件实例
被缓存的组件会多两个生命周期
actived和deactived
actived:激活时,组件被看到时触发
deactive:失活时,离开页面,组件看不见时触发
作用:组件一旦被缓存,就不涉及到组件的创建和销毁了,那这个时候组件的什么beforecreat,created,beforemount,mounted等对应的钩子就不会被触发了