目录
一、实现功能需求及步骤
二、初始结构代码
2.1. main.js
2.2. App.vue
2.3. index.js
2.4. Layout.vue
2.5. Article.vue
2.6. ArticleDetail.vue
2.7. Collect.vue
2.8. Like.vue
2.9. User.vue
三、功能实现
3.1. 配置一二级路由
3.2. 配置路由出口/链接/高亮显示
3.3. 首页请求渲染
3.4. 主页路由跳转详情页传参
3.5. 默认请求路径跳转设置
3.6. 详情页跳转返回主页
3.7. 详情页渲染
3.8. 增加显示判断
3.9. 详情页返回首页定位到原始位置
一、实现功能需求及步骤
1. 配路由
① 首页 和 面经详情,两个一级路由
② 首页内嵌四个可切换页面 (嵌套二级路由)
2. 实现功能
① 首页请求渲染
② 跳转传参 到 详情页,详情页渲染
③ 组件缓存,优化性能
二、初始结构代码
2.1. main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'Vue.config.productionTip = falsenew Vue({render: h => h(App),router
}).$mount('#app')
2.2. App.vue
<template><div class="h5-wrapper"><!-- 路由出口 --><router-view></router-view></div>
</template><script>
export default {name: "h5-wrapper",
}
</script><style>
body {margin: 0;padding: 0;
}
</style>
<style lang="less" scoped>
.h5-wrapper {.content {margin-bottom: 51px;}.tabbar {position: fixed;left: 0;bottom: 0;width: 100%;height: 50px;line-height: 50px;text-align: center;display: flex;background: #fff;border-top: 1px solid #e4e4e4;a {flex: 1;text-decoration: none;font-size: 14px;color: #333;-webkit-tap-highlight-color: transparent;&.router-link-active {color: #fa0;}}}
}
</style>
2.3. index.js
import Vue from 'vue'
import VueRouter from "vue-router";
Vue.use(VueRouter)const router = new VueRouter({routes: []
})export default router
2.4. Layout.vue
<template><div class="h5-wrapper"><div class="content">内容</div><nav class="tabbar"><a href="#/article">面经</a><a href="#/collect">收藏</a><a href="#/like">喜欢</a><a href="#/user">我的</a></nav></div>
</template><script>
export default {name: "LayoutPage",
}
</script><style>
body {margin: 0;padding: 0;
}
</style>
<style lang="less" scoped>
.h5-wrapper {.content {margin-bottom: 51px;}.tabbar {position: fixed;left: 0;bottom: 0;width: 100%;height: 50px;line-height: 50px;text-align: center;display: flex;background: #fff;border-top: 1px solid #e4e4e4;a {flex: 1;text-decoration: none;font-size: 14px;color: #333;-webkit-tap-highlight-color: transparent;}}
}
</style>
2.5. Article.vue
<template><div class="article-page"><divclass="article-item"><div class="head"><img src="http://teachoss.itheima.net/heimaQuestionMiniapp/%E5%AE%98%E6%96%B9%E9%BB%98%E8%AE%A4%E5%A4%B4%E5%83%8F%402x.png" alt="" /><div class="con"><p class="title">百度前端面经</p><p class="other">青春, 那么骚 | 2022-01-20</p></div></div><div class="body">虽然百度这几年发展势头落后于AT,甚至快被京东赶上了,毕竟瘦死的骆驼比马大,面试还是相当有难度和水准的。一面1.询问你的项目经验、学习经历、主修语言(照实答)2.解释ES6的暂时性死区( let 和 var 的区别)3.箭头函数、闭包、异步(老生常谈,参见上文)4.高阶函数(呃……我真不太清楚这是啥,听起来挺像闭包的)5.求N的阶乘末尾有多少个0,在线码代码或讲思路(求因数,统计2、5、10的个数</div><div class="foot">点赞 44 | 浏览 315</div></div></div>
</template><script>
// 请求地址: https://mock.boxuegu.com/mock/3083/articles
// 请求方式: get
export default {name: 'ArticlePage',data () {return {}}
}
</script><style lang="less" scoped>
.article-page {background: #f5f5f5;
}
.article-item {margin-bottom: 10px;background: #fff;padding: 10px 15px;.head {display: flex;img {width: 40px;height: 40px;border-radius: 50%;overflow: hidden;}.con {flex: 1;overflow: hidden;padding-left: 15px;p {margin: 0;line-height: 1.5;&.title {text-overflow: ellipsis;overflow: hidden;width: 100%;white-space: nowrap;}&.other {font-size: 10px;color: #999;}}}}.body {font-size: 14px;color: #666;line-height: 1.6;margin-top: 10px;overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;}.foot {font-size: 12px;color: #999;margin-top: 10px;}
}
</style>
2.6. ArticleDetail.vue
<template><div class="article-detail-page"><nav class="nav"><span class="back"><</span> 面经详情</nav><header class="header"><h1>百度前端面经</h1><p>2022-01-20 | 315 浏览量 | 44 点赞数</p><p><imgsrc="http://teachoss.itheima.net/heimaQuestionMiniapp/%E5%AE%98%E6%96%B9%E9%BB%98%E8%AE%A4%E5%A4%B4%E5%83%8F%402x.png"alt=""/><span>青春少年</span></p></header><main class="body">虽然百度这几年发展势头落后于AT, 甚至快被京东赶上了,毕竟瘦死的骆驼比马大,面试还是相当有难度和水准的, 一面.....</main></div>
</template><script>
// 请求地址: https://mock.boxuegu.com/mock/3083/articles/:id
// 请求方式: get
export default {name: "ArticleDetailPage",data() {return {}}
}
</script><style lang="less" scoped>
.article-detail-page {.nav {height: 44px;border-bottom: 1px solid #e4e4e4;line-height: 44px;text-align: center;.back {font-size: 18px;color: #666;position: absolute;left: 10px;top: 0;transform: scale(1, 1.5);}}.header {padding: 0 15px;p {color: #999;font-size: 12px;display: flex;align-items: center;}img {width: 40px;height: 40px;border-radius: 50%;overflow: hidden;}}.body {padding: 0 15px;}
}
</style>
2.7. Collect.vue
<template><div>Collect</div>
</template><script>
export default {name: 'CollectPage'
}
</script>
2.8. Like.vue
<template><div>Like</div>
</template><script>
export default {name: 'LikePage'
}
</script>
2.9. User.vue
<template><div>User</div>
</template><script>
export default {name: 'UserPage'
}
</script>
三、功能实现
3.1. 配置一二级路由
一级路由包括首页(Layout)和面经详情(ArticleDetail),子路由通过children属性来实现:
import ArticleDetail from '@/views/ArticleDetail.vue';
import Layout from '@/views/Layout.vue';
import Article from '@/views/Article.vue';
import Collect from '@/views/Collect.vue';
import Like from '@/views/Like.vue';
import User from '@/views/User.vue';
import Vue from 'vue'
import VueRouter from "vue-router";
Vue.use(VueRouter)const router = new VueRouter({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
3.2. 配置路由出口/链接/高亮显示
<template><div class="h5-wrapper"><div class="content"><!-- 配置二级路由出口,匹配到的二级路由组件就会在此展示 --><router-view></router-view></div><nav class="tabbar"><!-- 导航高亮显示效果1. 将a标签,替换成router-link 并将 a标签 href属性 改成 to2. 结合高亮类名实现高亮效果 router-link-active--><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: "LayoutPage",
}
</script><style>
body {margin: 0;padding: 0;
}
</style>
<style lang="less" scoped>
.h5-wrapper {.content {margin-bottom: 51px;}.tabbar {position: fixed;left: 0;bottom: 0;width: 100%;height: 50px;line-height: 50px;text-align: center;display: flex;background: #fff;border-top: 1px solid #e4e4e4;a {flex: 1;text-decoration: none;font-size: 14px;color: #333;-webkit-tap-highlight-color: transparent;}// 自定义 Vue路由高亮类名 的颜色a.router-link-active {color: orange;}}
}
</style>
3.3. 首页请求渲染
1. 安装axios
2. 确认请求方式/请求地址/请求参数
3. created中发请求,获取数据并存储
4. 页面动态渲染
3.4. 主页路由跳转详情页传参
下面两种传参形式均可,查询传参适合多个参数传递,动态路由传参适合单个参数传递:
1. 查询参数传参 ?参数=参数值 => this.$route.query.参数名
2. 动态路由传参 改造路由 => /路径/参数 => this.$route.params.参数名
3.5. 默认请求路径跳转设置
将首次访问页面定位跳转到Article.vue页面
3.6. 详情页跳转返回主页
3.7. 详情页渲染
3.8. 增加显示判断
当后端请求过来的article数据还未获取到赋值时,不显示,避免页面短暂空白
3.9. 详情页返回首页定位到原始位置
从主页的指定位置A跳转到详情页,返回后定位到首页浏览的原始位置A:
1. 组件缓存 keep-alive
keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而非销毁它们
keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中。
2. keep-alive的优点
在组件切换过程中 把切换出去的组件保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。
3. keep-alive的三个属性
① include : 组件名数组,只有匹配的组件会被缓存
② exclude : 组件名数组,任何匹配的组件都不会被缓存
③ max : 最多可以缓存多少组件实例
4. keep-alive的使用会触发两个生命周期函数
activated 当组件被激活(使用)的时候触发 → 进入这个页面的时候触发
deactivated 当组件不被使用的时候触发 → 离开这个页面的时候触发
组件缓存后就不会执行组件的created, mounted, destroyed 等钩子了
所以其提供了actived 和 deactived钩子,帮我们实现业务需求。