项目源码与所需资料
链接:https://pan.baidu.com/s/1azwRyyFwXz5elhQL0BhkCA?pwd=8z59
提取码:8z59
文章目录
demo13-搭建前台环境、首页数据显示
1.服务端渲染技术NUXT
1.以前是客户端发送ajax请求给服务端,然后服务端返回数据给客户端。不利于网站进行SEO(老师解释了,我听不懂)
2.下面这种方式利于SEO:客户端请求服务端时,服务端的node.js会请求tomcat得到数据,得到数据后在node.js中把数据做封装,然后将数据一次性返回给客户端
和ajax的区别是:ajax方式是客户端请求服务端的tomcat;而nuxt方式是服务端的node.js请求服务端的tomcat,客户端只负责显示数据,请求过程是通过node.js实现的,请求数据是发生在服务端而不像ajax那样那样发生在客户端。NUXT是对node.js的封装,所以我们这里使用NUXT框架来搭建前台系统
2.NUXT框架介绍
2.1NUXT环境初始化
1.在资料中提供了nuxt的压缩文件(已经下载好依赖了,直接用就行)
2.解压后得到vue-front-1010文件夹,将该文件夹复制粘贴到工作区vs1010中
3.在vue-front-1010文件夹上右键选择"终端中打开"
4.使用命令npm run dev启动项目
5.看到这个就是启动成功了
6.在地址栏输入http://localhost:3000/
进行访问
7.会出现这样的警告,不用管,对项目没影响
2.2NUXT目录结构
.nuxt
:就相当于java的.class文件,里面是编译后的内容assets
:一般存放项目中使用到的静态资源,比如css、js、img…components
:存放项目中用到的组件layouts
:该目录下有一个default.vue文件,该文件用于定义网页布局(页面的头信息和尾信息)middleware
:也可以放一些相关组件node_modules
:存放下载好的依赖pages
:存放项目中的页面,该目录下的index.vue是默认首页面nuxt.config.js
:NUXT框架的核心配置文件
显示页面的流程:先加载layouts下的default.vue页面,然后在该页面中使用nuxt标签将其它页面引入过来
我们这个项目的后台的前端项目使用的vue-admin框架是基于vue和element-ui实现的。但是我们项目的前台的前端项目使用的NUXT框架只基于vue实现,本身并没有集成element-ui,如果我们想使用element-ui就需要将element-ui引入过来,否则不能使用element-ui中的组件
3.整合项目首页面
3.1幻灯片插件
1.使用如下命令安装幻灯片插件
npm install vue-awesome-swiper
2.配置幻灯片插件
①在plugins文件夹下创建文件nuxt-swiper-plugin.js并编写代码
import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper/dist/ssr'
Vue.use(VueAwesomeSwiper)
②在nuxt.config.js文件中配置插件
将plugins和css节点复制到module.exports节点下
plugins: [
{ src: '~/plugins/nuxt-swiper-plugin.js', ssr: false }
],
css: [
'swiper/dist/css/swiper.css'
],
3.2复制静态资源
1.删掉vs1010–>vue-front-1010–>assets下的README.md
2.静态资源在资料中已经提供
3.将上图中红框圈起来的静态资源复制粘贴到vs1010–>vue-front-1010–>assets中
3.3定义布局
删掉layouts目录的default.vue页面中所有代码,然后将如下代码复制到default.vue页面中
<template>
<div class="in-wrap">
<!-- 公共头引入 -->
<header id="header">
<section class="container">
<h1 id="logo">
<a href="#" title="谷粒学院">
<img src="~/assets/img/logo.png" width="100%" alt="谷粒学院">
</a>
</h1>
<div class="h-r-nsl">
<ul class="nav">
<router-link to="/" tag="li" active-class="current" exact>
<a>首页</a>
</router-link>
<router-link to="/course" tag="li" active-class="current">
<a>课程</a>
</router-link>
<router-link to="/teacher" tag="li" active-class="current">
<a>名师</a>
</router-link>
<router-link to="/article" tag="li" active-class="current">
<a>文章</a>
</router-link>
<router-link to="/qa" tag="li" active-class="current">
<a>问答</a>
</router-link>
</ul>
<!-- / nav -->
<ul class="h-r-login">
<li id="no-login">
<a href="/sing_in" title="登录">
<em class="icon18 login-icon"> </em>
<span class="vam ml5">登录</span>
</a>
|
<a href="/sign_up" title="注册">
<span class="vam ml5">注册</span>
</a>
</li>
<li class="mr10 undis" id="is-login-one">
<a href="#" title="消息" id="headerMsgCountId">
<em class="icon18 news-icon"> </em>
</a>
<q class="red-point" style="display: none"> </q>
</li>
<li class="h-r-user undis" id="is-login-two">
<a href="#" title>
<img
src="~/assets/img/avatar-boy.gif"
width="30"
height="30"
class="vam picImg"
alt
>
<span class="vam disIb" id="userName"></span>
</a>
<a href="javascript:void(0)" title="退出" οnclick="exit();" class="ml5">退出</a>
</li>
<!-- /未登录显示第1 li;登录后显示第2,3 li -->
</ul>
<aside class="h-r-search">
<form action="#" method="post">
<label class="h-r-s-box">
<input type="text" placeholder="输入你想学的课程" name="queryCourse.courseName" value>
<button type="submit" class="s-btn">
<em class="icon18"> </em>
</button>
</label>
</form>
</aside>
</div>
<aside class="mw-nav-btn">
<div class="mw-nav-icon"></div>
</aside>
<div class="clear"></div>
</section>
</header>
<!-- /公共头引入 -->
<nuxt/>
<!-- 公共底引入 -->
<footer id="footer">
<section class="container">
<div class>
<h4 class="hLh30">
<span class="fsize18 f-fM c-999">友情链接</span>
</h4>
<ul class="of flink-list">
<li>
<a href="http://www.atguigu.com/" title="尚硅谷" target="_blank">尚硅谷</a>
</li>
</ul>
<div class="clear"></div>
</div>
<div class="b-foot">
<section class="fl col-7">
<section class="mr20">
<section class="b-f-link">
<a href="#" title="关于我们" target="_blank">关于我们</a>|
<a href="#" title="联系我们" target="_blank">联系我们</a>|
<a href="#" title="帮助中心" target="_blank">帮助中心</a>|
<a href="#" title="资源下载" target="_blank">资源下载</a>|
<span>服务热线:010-56253825(北京) 0755-85293825(深圳)</span>
<span>Email:info@atguigu.com</span>
</section>
<section class="b-f-link mt10">
<span>©2018课程版权均归谷粒学院所有 京ICP备17055252号</span>
</section>
</section>
</section>
<aside class="fl col-3 tac mt15">
<section class="gf-tx">
<span>
<img src="~/assets/img/wx-icon.png" alt>
</span>
</section>
<section class="gf-tx">
<span>
<img src="~/assets/img/wb-icon.png" alt>
</span>
</section>
</aside>
<div class="clear"></div>
</div>
</section>
</footer>
<!-- /公共底引入 -->
</div>
</template>
<script>
import "~/assets/css/reset.css";
import "~/assets/css/theme.css";
import "~/assets/css/global.css";
import "~/assets/css/web.css";
export default {};
</script>
3.4定义首页面
删掉pages目录的index.vue页面中所有代码,然后将如下代码复制到index.vue页面中
<template>
<div>
<!-- 幻灯片 开始 -->
<!-- 幻灯片 结束 -->
<div id="aCoursesList">
<!-- 网校课程 开始 -->
<div>
<section class="container">
<header class="comm-title">
<h2 class="tac">
<span class="c-333">热门课程</span>
</h2>
</header>
<div>
<article class="comm-course-list">
<ul class="of" id="bna">
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442295592705.jpg"
class="img-responsive"
alt="听力口语"
>
<div class="cc-mask">
<a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" title="听力口语" class="course-title fsize18 c-333">听力口语</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">9634人学习</i>
|
<i class="c-999 f-fA">9634评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442295581911.jpg"
class="img-responsive"
alt="Java精品课程"
>
<div class="cc-mask">
<a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" title="Java精品课程" class="course-title fsize18 c-333">Java精品课程</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">501人学习</i>
|
<i class="c-999 f-fA">501评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442295604295.jpg"
class="img-responsive"
alt="C4D零基础"
>
<div class="cc-mask">
<a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" title="C4D零基础" class="course-title fsize18 c-333">C4D零基础</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">300人学习</i>
|
<i class="c-999 f-fA">300评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442302831779.jpg"
class="img-responsive"
alt="数学给宝宝带来的兴趣"
>
<div class="cc-mask">
<a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" title="数学给宝宝带来的兴趣" class="course-title fsize18 c-333">数学给宝宝带来的兴趣</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">256人学习</i>
|
<i class="c-999 f-fA">256评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442295455437.jpg"
class="img-responsive"
alt="零基础入门学习Python课程学习"
>
<div class="cc-mask">
<a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a
href="#"
title="零基础入门学习Python课程学习"
class="course-title fsize18 c-333"
>零基础入门学习Python课程学习</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">137人学习</i>
|
<i class="c-999 f-fA">137评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442295570359.jpg"
class="img-responsive"
alt="MySql从入门到精通"
>
<div class="cc-mask">
<a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" title="MySql从入门到精通" class="course-title fsize18 c-333">MySql从入门到精通</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">125人学习</i>
|
<i class="c-999 f-fA">125评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442302852837.jpg"
class="img-responsive"
alt="搜索引擎优化技术"
>
<div class="cc-mask">
<a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" title="搜索引擎优化技术" class="course-title fsize18 c-333">搜索引擎优化技术</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">123人学习</i>
|
<i class="c-999 f-fA">123评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442295379715.jpg"
class="img-responsive"
alt="20世纪西方音乐"
>
<div class="cc-mask">
<a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" title="20世纪西方音乐" class="course-title fsize18 c-333">20世纪西方音乐</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">34人学习</i>
|
<i class="c-999 f-fA">34评论</i>
</span>
</section>
</div>
</li>
</ul>
<div class="clear"></div>
</article>
<section class="tac pt20">
<a href="#" title="全部课程" class="comm-btn c-btn-2">全部课程</a>
</section>
</div>
</section>
</div>
<!-- /网校课程 结束 -->
<!-- 网校名师 开始 -->
<div>
<section class="container">
<header class="comm-title">
<h2 class="tac">
<span class="c-333">名师大咖</span>
</h2>
</header>
<div>
<article class="i-teacher-list">
<ul class="of">
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="姚晨">
<img alt="姚晨" src="~/assets/photo/teacher/1442297885942.jpg">
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="姚晨" class="fsize18 c-666">姚晨</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">北京师范大学法学院副教授</span>
</div>
<div class="mt15 i-q-txt">
<p
class="c-999 f-fA"
>北京师范大学法学院副教授、清华大学法学博士。自2004年至今已有9年的司法考试培训经验。长期从事司法考试辅导,深知命题规律,了解解题技巧。内容把握准确,授课重点明确,层次分明,调理清晰,将法条法理与案例有机融合,强调综合,深入浅出。</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="谢娜">
<img alt="谢娜" src="~/assets/photo/teacher/1442297919077.jpg">
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="谢娜" class="fsize18 c-666">谢娜</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">资深课程设计专家,专注10年AACTP美国培训协会认证导师</span>
</div>
<div class="mt15 i-q-txt">
<p
class="c-999 f-fA"
>十年课程研发和培训咨询经验,曾任国企人力资源经理、大型外企培训经理,负责企业大学和培训体系搭建;曾任专业培训机构高级顾问、研发部总监,为包括广东移动、东莞移动、深圳移动、南方电网、工商银行、农业银行、民生银行、邮储银行、TCL集团、清华大学继续教育学院、中天路桥、广西扬翔股份等超过200家企业提供过培训与咨询服务,并担任近50个大型项目的总负责人。</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="刘德华">
<img alt="刘德华" src="~/assets/photo/teacher/1442297927029.jpg">
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="刘德华" class="fsize18 c-666">刘德华</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">上海师范大学法学院副教授</span>
</div>
<div class="mt15 i-q-txt">
<p
class="c-999 f-fA"
>上海师范大学法学院副教授、清华大学法学博士。自2004年至今已有9年的司法考试培训经验。长期从事司法考试辅导,深知命题规律,了解解题技巧。内容把握准确,授课重点明确,层次分明,调理清晰,将法条法理与案例有机融合,强调综合,深入浅出。</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="周润发">
<img alt="周润发" src="~/assets/photo/teacher/1442297935589.jpg">
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="周润发" class="fsize18 c-666">周润发</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">考研政治辅导实战派专家,全国考研政治命题研究组核心成员。</span>
</div>
<div class="mt15 i-q-txt">
<p
class="c-999 f-fA"
>法学博士,北京师范大学马克思主义学院副教授,专攻毛泽东思想概论、邓小平理论,长期从事考研辅导。出版著作两部,发表学术论文30余篇,主持国家社会科学基金项目和教育部重大课题子课题各一项,参与中央实施马克思主义理论研究和建设工程项目。</p>
</div>
</section>
</li>
</ul>
<div class="clear"></div>
</article>
<section class="tac pt20">
<a href="#" title="全部讲师" class="comm-btn c-btn-2">全部讲师</a>
</section>
</div>
</section>
</div>
<!-- /网校名师 结束 -->
</div>
</div>
</template>
<script>
export default {
}
</script>
3.5整合幻灯片
1.在index.vue页面中将下述代码复制粘贴到图中所示位置
<div v-swiper:mySwiper="swiperOption">
<div class="swiper-wrapper">
<div class="swiper-slide" style="background: #040B1B;">
<a target="_blank" href="/">
<img src="~/assets/photo/banner/1525939573202.jpg" alt="首页banner">
</a>
</div>
<div class="swiper-slide" style="background: #040B1B;">
<a target="_blank" href="/">
<img src="~/assets/photo/banner/1525939573202.jpg" alt="首页banner">
</a>
</div>
</div>
<div class="swiper-pagination swiper-pagination-white"></div>
<div class="swiper-button-prev swiper-button-white" slot="button-prev"></div>
<div class="swiper-button-next swiper-button-white" slot="button-next"></div>
</div>
2.将index.vue页面中如下方框圈起来的部分删掉
3.将下述代码复制粘贴到刚刚删除的位置
<script>
export default {
data () {
return {
swiperOption: {
//配置分页
pagination: {
el: '.swiper-pagination'//分页的dom节点
},
//配置导航
navigation: {
nextEl: '.swiper-button-next',//下一页dom节点
prevEl: '.swiper-button-prev'//前一页dom节点
}
}
}
}
}
</script>
4.将index.vue页面第14行的1525939573202.jpg
改为153525d0ef15459596.jpg
3.6看效果
保存修改后在地址栏输入http://localhost:3000/
看效果
4.路由
4.1固定路由
1.固定路由就是:路由是固定的,不发生变化
2.比如:头信息中的首页、课程、名师、文章、问答
是通过to属性来设置路由跳转的地址
3.以课程为例,做法是:在pages文件夹下创建course文件夹,然后在course文件夹下创建index.vue页面
4.2动态路由
1.动态路由就是:每次生成的路由地址不一样,比如课程详情
2.如果我们需要根据id查询一条记录,就需要使用动态路由。NUXT的动态路由是以下划线开头的vue文件,参数名为下划线后边的文件名,如_id.vue
5.整合页面
5.1整合课程页面
在pages文件夹下创建course文件夹,然后在course文件夹下创建index.vue页面并将下述代码复制过来
<template>
<div id="aCoursesList" class="bg-fa of">
<!-- /课程列表 开始 -->
<section class="container">
<header class="comm-title">
<h2 class="fl tac">
<span class="c-333">全部课程</span>
</h2>
</header>
<section class="c-sort-box">
<section class="c-s-dl">
<dl>
<dt>
<span class="c-999 fsize14">课程类别</span>
</dt>
<dd class="c-s-dl-li">
<ul class="clearfix">
<li>
<a title="全部" href="#">全部</a>
</li>
<li>
<a title="数据库" href="#">数据库</a>
</li>
<li class="current">
<a title="外语考试" href="#">外语考试</a>
</li>
<li>
<a title="教师资格证" href="#">教师资格证</a>
</li>
<li>
<a title="公务员" href="#">公务员</a>
</li>
<li>
<a title="移动开发" href="#">移动开发</a>
</li>
<li>
<a title="操作系统" href="#">操作系统</a>
</li>
</ul>
</dd>
</dl>
<dl>
<dt>
<span class="c-999 fsize14"></span>
</dt>
<dd class="c-s-dl-li">
<ul class="clearfix">
<li>
<a title="职称英语" href="#">职称英语</a>
</li>
<li>
<a title="英语四级" href="#">英语四级</a>
</li>
<li>
<a title="英语六级" href="#">英语六级</a>
</li>
</ul>
</dd>
</dl>
<div class="clear"></div>
</section>
<div class="js-wrap">
<section class="fr">
<span class="c-ccc">
<i class="c-master f-fM">1</i>/
<i class="c-666 f-fM">1</i>
</span>
</section>
<section class="fl">
<ol class="js-tap clearfix">
<li>
<a title="关注度" href="#">关注度</a>
</li>
<li>
<a title="最新" href="#">最新</a>
</li>
<li class="current bg-orange">
<a title="价格" href="#">价格
<span>↓</span>
</a>
</li>
</ol>
</section>
</div>
<div class="mt40">
<!-- /无数据提示 开始-->
<section class="no-data-wrap">
<em class="icon30 no-data-ico"> </em>
<span class="c-666 fsize14 ml10 vam">没有相关数据,小编正在努力整理中...</span>
</section>
<!-- /无数据提示 结束-->
<article class="comm-course-list">
<ul class="of" id="bna">
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img src="~/assets/photo/course/1442295592705.jpg" class="img-responsive" alt="听力口语">
<div class="cc-mask">
<a href="/course/1" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="/course/1" title="听力口语" class="course-title fsize18 c-333">听力口语</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">9634人学习</i>
|
<i class="c-999 f-fA">9634评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img src="~/assets/photo/course/1442295581911.jpg" class="img-responsive" alt="Java精品课程">
<div class="cc-mask">
<a href="/course/1" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="/course/1" title="Java精品课程" class="course-title fsize18 c-333">Java精品课程</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">501人学习</i>
|
<i class="c-999 f-fA">501评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img src="~/assets/photo/course/1442295604295.jpg" class="img-responsive" alt="C4D零基础">
<div class="cc-mask">
<a href="/course/1" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="/course/1" title="C4D零基础" class="course-title fsize18 c-333">C4D零基础</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">300人学习</i>
|
<i class="c-999 f-fA">300评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442302831779.jpg"
class="img-responsive"
alt="数学给宝宝带来的兴趣"
>
<div class="cc-mask">
<a href="/course/1" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="/course/1" title="数学给宝宝带来的兴趣" class="course-title fsize18 c-333">数学给宝宝带来的兴趣</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">256人学习</i>
|
<i class="c-999 f-fA">256评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442295455437.jpg"
class="img-responsive"
alt="零基础入门学习Python课程学习"
>
<div class="cc-mask">
<a href="/course/1" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a
href="/course/1"
title="零基础入门学习Python课程学习"
class="course-title fsize18 c-333"
>零基础入门学习Python课程学习</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">137人学习</i>
|
<i class="c-999 f-fA">137评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442295570359.jpg"
class="img-responsive"
alt="MySql从入门到精通"
>
<div class="cc-mask">
<a href="/course/1" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="/course/1" title="MySql从入门到精通" class="course-title fsize18 c-333">MySql从入门到精通</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">125人学习</i>
|
<i class="c-999 f-fA">125评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img src="~/assets/photo/course/1442302852837.jpg" class="img-responsive" alt="搜索引擎优化技术">
<div class="cc-mask">
<a href="/course/1" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="/course/1" title="搜索引擎优化技术" class="course-title fsize18 c-333">搜索引擎优化技术</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">123人学习</i>
|
<i class="c-999 f-fA">123评论</i>
</span>
</section>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img src="~/assets/photo/course/1442295379715.jpg" class="img-responsive" alt="20世纪西方音乐">
<div class="cc-mask">
<a href="/course/1" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="/course/1" title="20世纪西方音乐" class="course-title fsize18 c-333">20世纪西方音乐</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">34人学习</i>
|
<i class="c-999 f-fA">34评论</i>
</span>
</section>
</div>
</li>
</ul>
<div class="clear"></div>
</article>
</div>
<!-- 公共分页 开始 -->
<div>
<div class="paging">
<a class="undisable" title>首</a>
<a id="backpage" class="undisable" href="#" title><</a>
<a href="#" title class="current undisable">1</a>
<a href="#" title>2</a>
<a id="nextpage" href="#" title>></a>
<a href="#" title>末</a>
<div class="clear"></div>
</div>
</div>
<!-- 公共分页 结束 -->
</section>
</section>
<!-- /课程列表 结束 -->
</div>
</template>
<script>
export default {};
</script>
5.2整合课程详情页面
在pages下的course目录下创建_id.vue页面,然后将下述代码复制过来
<template>
<div id="aCoursesList" class="bg-fa of">
<!-- /课程详情 开始 -->
<section class="container">
<section class="path-wrap txtOf hLh30">
<a href="#" title class="c-999 fsize14">首页</a>
\
<a href="#" title class="c-999 fsize14">课程列表</a>
\
<span class="c-333 fsize14">Java精品课程</span>
</section>
<div>
<article class="c-v-pic-wrap" style="height: 357px;">
<section class="p-h-video-box" id="videoPlay">
<img src="~/assets/photo/course/1442295581911.jpg" alt="Java精品课程" class="dis c-v-pic">
</section>
</article>
<aside class="c-attr-wrap">
<section class="ml20 mr15">
<h2 class="hLh30 txtOf mt15">
<span class="c-fff fsize24">Java精品课程</span>
</h2>
<section class="c-attr-jg">
<span class="c-fff">价格:</span>
<b class="c-yellow" style="font-size:24px;">¥0.00</b>
</section>
<section class="c-attr-mt c-attr-undis">
<span class="c-fff fsize14">主讲: 唐嫣 </span>
</section>
<section class="c-attr-mt of">
<span class="ml10 vam">
<em class="icon18 scIcon"></em>
<a class="c-fff vam" title="收藏" href="#" >收藏</a>
</span>
</section>
<section class="c-attr-mt">
<a href="#" title="立即观看" class="comm-btn c-btn-3">立即观看</a>
</section>
</section>
</aside>
<aside class="thr-attr-box">
<ol class="thr-attr-ol clearfix">
<li>
<p> </p>
<aside>
<span class="c-fff f-fM">购买数</span>
<br>
<h6 class="c-fff f-fM mt10">150</h6>
</aside>
</li>
<li>
<p> </p>
<aside>
<span class="c-fff f-fM">课时数</span>
<br>
<h6 class="c-fff f-fM mt10">20</h6>
</aside>
</li>
<li>
<p> </p>
<aside>
<span class="c-fff f-fM">浏览数</span>
<br>
<h6 class="c-fff f-fM mt10">501</h6>
</aside>
</li>
</ol>
</aside>
<div class="clear"></div>
</div>
<!-- /课程封面介绍 -->
<div class="mt20 c-infor-box">
<article class="fl col-7">
<section class="mr30">
<div class="i-box">
<div>
<section id="c-i-tabTitle" class="c-infor-tabTitle c-tab-title">
<a name="c-i" class="current" title="课程详情">课程详情</a>
</section>
</div>
<article class="ml10 mr10 pt20">
<div>
<h6 class="c-i-content c-infor-title">
<span>课程介绍</span>
</h6>
<div class="course-txt-body-wrap">
<section class="course-txt-body">
<p>
Java的发展历史,可追溯到1990年。当时Sun Microsystem公司为了发展消费性电子产品而进行了一个名为Green的项目计划。该计划
负责人是James Gosling。起初他以C++来写一种内嵌式软件,可以放在烤面包机或PAD等小型电子消费设备里,使得机器更聪明,具有人工智
能。但他发现C++并不适合完成这类任务!因为C++常会有使系统失效的程序错误,尤其是内存管理,需要程序设计师记录并管理内存资源。这给设计师们造成
极大的负担,并可能产生许多bugs。
<br>为了解决所遇到的问题,Gosling决定要发展一种新的语言,来解决C++的潜在性危险问题,这个语言名叫Oak。Oak是一种可移植性语言,也就是一种平台独立语言,能够在各种芯片上运行。
<br>1994年,Oak技术日趋成熟,这时网络正开始蓬勃发展。Oak研发小组发现Oak很适合作为一种网络程序语言。因此发展了一个能与Oak配合的浏
览器--WebRunner,后更名为HotJava,它证明了Oak是一种能在网络上发展的程序语言。由于Oak商标已被注册,工程师们便想到以自己常
享用的咖啡(Java)来重新命名,并于Sun World 95中被发表出来。
</p>
</section>
</div>
</div>
<!-- /课程介绍 -->
<div class="mt50">
<h6 class="c-g-content c-infor-title">
<span>课程大纲</span>
</h6>
<section class="mt20">
<div class="lh-menu-wrap">
<menu id="lh-menu" class="lh-menu mt10 mr10">
<ul>
<!-- 文件目录 -->
<li class="lh-menu-stair">
<a href="javascript: void(0)" title="第一章" class="current-1">
<em class="lh-menu-i-1 icon18 mr10"></em>第一章
</a>
<ol class="lh-menu-ol" style="display: block;">
<li class="lh-menu-second ml30">
<a href="#" title>
<span class="fr">
<i class="free-icon vam mr10">免费试听</i>
</span>
<em class="lh-menu-i-2 icon16 mr5"> </em>第一节
</a>
</li>
<li class="lh-menu-second ml30">
<a href="#" title class="current-2">
<em class="lh-menu-i-2 icon16 mr5"> </em>第二节
</a>
</li>
</ol>
</li>
</ul>
</menu>
</div>
</section>
</div>
<!-- /课程大纲 -->
</article>
</div>
</section>
</article>
<aside class="fl col-3">
<div class="i-box">
<div>
<section class="c-infor-tabTitle c-tab-title">
<a title href="javascript:void(0)">主讲讲师</a>
</section>
<section class="stud-act-list">
<ul style="height: auto;">
<li>
<div class="u-face">
<a href="#">
<img src="~/assets/photo/teacher/1442297969808.jpg" width="50" height="50" alt>
</a>
</div>
<section class="hLh30 txtOf">
<a class="c-333 fsize16 fl" href="#">周杰伦</a>
</section>
<section class="hLh20 txtOf">
<span class="c-999">毕业于北京大学数学系</span>
</section>
</li>
</ul>
</section>
</div>
</div>
</aside>
<div class="clear"></div>
</div>
</section>
<!-- /课程详情 结束 -->
</div>
</template>
<script>
export default {};
</script>
5.3整合名师页面
在pages文件夹下创建teacher文件夹,然后在teacher文件夹下创建index.vue页面并将下述代码复制过来
<template>
<div id="aCoursesList" class="bg-fa of">
<!-- 讲师列表 开始 -->
<section class="container">
<header class="comm-title all-teacher-title">
<h2 class="fl tac">
<span class="c-333">全部讲师</span>
</h2>
<section class="c-tab-title">
<a id="subjectAll" title="全部" href="#">全部</a>
<!-- <c:forEach var="subject" items="${subjectList }">
<a id="${subject.subjectId}" title="${subject.subjectName }" href="javascript:void(0)" οnclick="submitForm(${subject.subjectId})">${subject.subjectName }</a>
</c:forEach>-->
</section>
</header>
<section class="c-sort-box unBr">
<div>
<!-- /无数据提示 开始-->
<section class="no-data-wrap">
<em class="icon30 no-data-ico"> </em>
<span class="c-666 fsize14 ml10 vam">没有相关数据,小编正在努力整理中...</span>
</section>
<!-- /无数据提示 结束-->
<article class="i-teacher-list">
<ul class="of">
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="姚晨" target="_blank">
<img src="~/assets/photo/teacher/1442297885942.jpg" alt>
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="姚晨" target="_blank" class="fsize18 c-666">姚晨</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">北京师范大学法学院副教授、清华大学法学博士。自2004年至今已有9年的司法考试培训经验。长期从事司法考试辅导,深知命题规律,了解解题技巧。内容把握准确,授课重点明确,层次分明,调理清晰,将法条法理与案例有机融合,强调综合,深入浅出。</span>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">北京师范大学法学院副教授</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="谢娜" target="_blank">
<img src="~/assets/photo/teacher/1442297919077.jpg" alt>
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="谢娜" target="_blank" class="fsize18 c-666">谢娜</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">十年课程研发和培训咨询经验,曾任国企人力资源经理、大型外企培训经理,负责企业大学和培训体系搭建;曾任专业培训机构高级顾问、研发部总监,为包括广东移动、东莞移动、深圳移动、南方电网、工商银行、农业银行、民生银行、邮储银行、TCL集团、清华大学继续教育学院、中天路桥、广西扬翔股份等超过200家企业提供过培训与咨询服务,并担任近50个大型项目的总负责人。</span>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">资深课程设计专家,专注10年AACTP美国培训协会认证导师</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="刘德华" target="_blank">
<img src="~/assets/photo/teacher/1442297927029.jpg" alt>
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="刘德华" target="_blank" class="fsize18 c-666">刘德华</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">上海师范大学法学院副教授、清华大学法学博士。自2004年至今已有9年的司法考试培训经验。长期从事司法考试辅导,深知命题规律,了解解题技巧。内容把握准确,授课重点明确,层次分明,调理清晰,将法条法理与案例有机融合,强调综合,深入浅出。</span>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">上海师范大学法学院副教授</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="周润发" target="_blank">
<img src="~/assets/photo/teacher/1442297935589.jpg" alt>
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="周润发" target="_blank" class="fsize18 c-666">周润发</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">法学博士,北京师范大学马克思主义学院副教授,专攻毛泽东思想概论、邓小平理论,长期从事考研辅导。出版著作两部,发表学术论文30余篇,主持国家社会科学基金项目和教育部重大课题子课题各一项,参与中央实施马克思主义理论研究和建设工程项目。</span>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">考研政治辅导实战派专家,全国考研政治命题研究组核心成员。</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="钟汉良" target="_blank">
<img src="~/assets/photo/teacher/1442298121626.jpg" alt>
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="钟汉良" target="_blank" class="fsize18 c-666">钟汉良</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">具备深厚的数学思维功底、丰富的小学教育经验,授课风格生动活泼,擅长用形象生动的比喻帮助理解、简单易懂的语言讲解难题,深受学生喜欢</span>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">毕业于师范大学数学系,热爱教育事业,执教数学思维6年有余</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="唐嫣" target="_blank">
<img src="~/assets/photo/teacher/1442297957332.jpg" alt>
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="唐嫣" target="_blank" class="fsize18 c-666">唐嫣</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">中国科学院数学与系统科学研究院应用数学专业博士,研究方向为数字图像处理,中国工业与应用数学学会会员。参与全国教育科学“十五”规划重点课题“信息化进程中的教育技术发展研究”的子课题“基与课程改革的资源开发与应用”,以及全国“十五”科研规划全国重点项目“掌上型信息技术产品在教学中的运用和开发研究”的子课题“用技术学数学”。</span>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">中国人民大学附属中学数学一级教师</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="周杰伦" target="_blank">
<img src="~/assets/photo/teacher/1442297969808.jpg" alt>
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="周杰伦" target="_blank" class="fsize18 c-666">周杰伦</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">中教一级职称。讲课极具亲和力。</span>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">毕业于北京大学数学系</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="陈伟霆" target="_blank">
<img src="~/assets/photo/teacher/1442297977255.jpg" alt>
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" title="陈伟霆" target="_blank" class="fsize18 c-666">陈伟霆</a>
</div>
<div class="hLh30 txtOf tac">
<span
class="fsize14 c-999"
>政治学博士、管理学博士后,北京师范大学马克思主义学院副教授。多年来总结出了一套行之有效的应试技巧与答题方法,针对性和实用性极强,能帮助考生在轻松中应考,在激励的竞争中取得高分,脱颖而出。</span>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">长期从事考研政治课讲授和考研命题趋势与应试对策研究。考研辅导新锐派的代表。</p>
</div>
</section>
</li>
</ul>
<div class="clear"></div>
</article>
</div>
<!-- 公共分页 开始 -->
<div>
<div class="paging">
<!-- undisable这个class是否存在,取决于数据属性hasPrevious -->
<a href="#" title="首页">首</a>
<a href="#" title="前一页"><</a>
<a href="#" title="第1页" class="current undisable">1</a>
<a href="#" title="第2页">2</a>
<a href="#" title="后一页">></a>
<a href="#" title="末页">末</a>
<div class="clear"></div>
</div>
</div>
<!-- 公共分页 结束 -->
</section>
</section>
<!-- /讲师列表 结束 -->
</div>
</template>
<script>
export default {};
</script>
5.4整合名师详情页面
在pages下的teacher目录下创建_id.vue页面,然后将下述代码复制过来
<template>
<div id="aCoursesList" class="bg-fa of">
<!-- 讲师介绍 开始 -->
<section class="container">
<header class="comm-title">
<h2 class="fl tac">
<span class="c-333">讲师介绍</span>
</h2>
</header>
<div class="t-infor-wrap">
<!-- 讲师基本信息 -->
<section class="fl t-infor-box c-desc-content">
<div class="mt20 ml20">
<section class="t-infor-pic">
<img src="~/assets/photo/teacher/1442297885942.jpg">
</section>
<h3 class="hLh30">
<span class="fsize24 c-333">姚晨 高级讲师</span>
</h3>
<section class="mt10">
<span class="t-tag-bg">北京师范大学法学院副教授</span>
</section>
<section class="t-infor-txt">
<p
class="mt20"
>北京师范大学法学院副教授、清华大学法学博士。自2004年至今已有9年的司法考试培训经验。长期从事司法考试辅导,深知命题规律,了解解题技巧。内容把握准确,授课重点明确,层次分明,调理清晰,将法条法理与案例有机融合,强调综合,深入浅出。</p>
</section>
<div class="clear"></div>
</div>
</section>
<div class="clear"></div>
</div>
<section class="mt30">
<div>
<header class="comm-title all-teacher-title c-course-content">
<h2 class="fl tac">
<span class="c-333">主讲课程</span>
</h2>
<section class="c-tab-title">
<a href="javascript: void(0)"> </a>
</section>
</header>
<!-- /无数据提示 开始-->
<section class="no-data-wrap">
<em class="icon30 no-data-ico"> </em>
<span class="c-666 fsize14 ml10 vam">没有相关数据,小编正在努力整理中...</span>
</section>
<!-- /无数据提示 结束-->
<article class="comm-course-list">
<ul class="of">
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img src="~/assets/photo/course/1442295455437.jpg" class="img-responsive" >
<div class="cc-mask">
<a href="#" title="开始学习" target="_blank" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" title="零基础入门学习Python课程学习" target="_blank" class="course-title fsize18 c-333">零基础入门学习Python课程学习</a>
</h3>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img src="~/assets/photo/course/1442295472860.jpg" class="img-responsive" >
<div class="cc-mask">
<a href="#" title="开始学习" target="_blank" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" title="影想力摄影小课堂" target="_blank" class="course-title fsize18 c-333">影想力摄影小课堂</a>
</h3>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img src="~/assets/photo/course/1442302831779.jpg" class="img-responsive" >
<div class="cc-mask">
<a href="#" title="开始学习" target="_blank" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" title="数学给宝宝带来的兴趣" target="_blank" class="course-title fsize18 c-333">数学给宝宝带来的兴趣</a>
</h3>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img src="~/assets/photo/course/1442295506745.jpg" class="img-responsive" >
<div class="cc-mask">
<a href="#" title="开始学习" target="_blank" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" title="国家教师资格考试专用" target="_blank" class="course-title fsize18 c-333">国家教师资格考试专用</a>
</h3>
</div>
</li>
</ul>
<div class="clear"></div>
</article>
</div>
</section>
</section>
<!-- /讲师介绍 结束 -->
</div>
</template>
<script>
export default {};
</script>
6.首页banner显示(后端)
6.1新建banner微服务
6.1.1创建子子模块service_cms
1.在service模块上右键选择New–>Module…
2.创建一个Maven项目
3.填写信息后点击"Finish"
6.1.2配置application.properties
创建配置文件application.properties并编写配置
# 服务端口
server.port=8004
# 服务名
spring.application.name=service-cms
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/guli?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
#配置mapper xml文件的路径
mybatis-plus.mapper-locations=classpath:com/atguigu/educms/mapper/xml/*.xml
#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
- 注意:数据库的账号密码写自己的
- 截图中第17行代码的作用:
- "demo10-课程管理"的"1.9.2解决问题"的第3步说过:如果编写xml文件手动写sql语句,需要分别在properties和xml中进行配置
6.1.3创建数据表crm_banner
1.创建这张表的脚本在资料的guli_cms.sql文件中
2.将创建crm_banner表的脚本复制到数据库中执行
CREATE TABLE `crm_banner` (
`id` char(19) NOT NULL DEFAULT '' COMMENT 'ID',
`title` varchar(20) DEFAULT '' COMMENT '标题',
`image_url` varchar(500) NOT NULL DEFAULT '' COMMENT '图片地址',
`link_url` varchar(500) DEFAULT '' COMMENT '链接地址',
`sort` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '排序',
`is_deleted` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '逻辑删除 1(true)已删除, 0(false)未删除',
`gmt_create` datetime NOT NULL COMMENT '创建时间',
`gmt_modified` datetime NOT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_name` (`title`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='首页banner表';
6.1.4向crm_banner表中插入数据
1.插入数据的sql语句在guli_cms.sql文件也有
2.向crm_banner表中插入数据的脚本复制到数据库中执行
INSERT INTO `crm_banner` VALUES ('1194556896025845762','test1','https://online-teach-file.oss-cn-beijing.aliyuncs.com/cms/2019/11/14/297acd3b-b592-4cfb-a446-a28310369675.jpg','/course',1,0,'2019-11-13 18:05:32','2019-11-18 10:28:22'),('1194607458461216769','test2','https://online-teach-file.oss-cn-beijing.aliyuncs.com/cms/2019/11/13/8f80790d-d736-4842-a6a4-4dcb0d684d4e.jpg','/teacher',2,0,'2019-11-13 21:26:27','2019-11-14 09:12:15');
6.1.5创建启动类
先在java目录下创建包com.atguigu.educms,然后在educms包下创建启动类CmsApplication
@SpringBootApplication
@ComponentScan({"com.atguigu"}) //指定扫描位置
public class CmsApplication {
public static void main(String[] args) {
SpringApplication.run(CmsApplication.class, args);
}
}
6.1.6生成代码
1.在service_cms模块的test包的java包下创建包codedemo
2.将service_edu模块的代码生成器CodeGenerator复制到上一步创建的codedemo包下
3.修改service_cms模块的代码生成器中的部分代码
4.在run方法上右键选择"Run ‘run()’"就可以生成代码了
5.给控制器CrmBannerController添加注解@CrossOrigin实现跨域,并且将请求路径中的crm-banner
改为banner
6.因为service_cms模块要操作数据库,所以需要在启动类上添加注解@MapperScan("com.atguigu.educms.mapper")
6.2创建banner服务接口
6.2.1分析
1.后台管理员可以进行curd操作,前台用户只能看到数据,不能进行curd操作
2.所以给控制器CrmBannerController改名为BannerAdminController,将请求路径/educms/banner
改为/educms/banneradmin
,是让后台管理员使用的
3.在控制层新建一个控制器BannerFrontController,是让前台用户使用的
@RestController
@RequestMapping("/educms/bannerfront")
@CrossOrigin
public class BannerFrontController {
}
6.2.2后台管理接口
在控制器BannerAdminController中编写代码
@Autowired
private CrmBannerService bannerService;
//1.分页查询banner
@GetMapping("pageBanner/{page}/{limit}")
public R pageBanner(@PathVariable Long page, @PathVariable Long limit) {
Page<CrmBanner> pageBanner = new Page<>(page, limit);
bannerService.page(pageBanner,null);
return R.ok().data("items", pageBanner.getRecords()).data("total", pageBanner.getTotal());
}
//2.添加banner
@PostMapping("addBanner")
public R addBanner(@RequestBody CrmBanner crmBanner) {
bannerService.save(crmBanner);
return R.ok();
}
//3.修改banner
//①根据id查询
@ApiOperation(value = "获取Banner")
@GetMapping("get/{id}")
public R get(@PathVariable String id) {
CrmBanner banner = bannerService.getById(id);
return R.ok().data("item", banner);
}
//②修改banner
@ApiOperation(value = "修改Banner")
@PutMapping("update")
public R updateById(@RequestBody CrmBanner banner) {
bannerService.updateById(banner);
return R.ok();
}
@ApiOperation(value = "删除Banner")
@DeleteMapping("remove/{id}")
public R remove(@PathVariable String id) {
bannerService.removeById(id);
return R.ok();
}
6.2.3前台系统接口
1.在控制器BannerFrontController中编写代码来查询banner
@Autowired
private CrmBannerService bannerService;
//根据banner的id进行降序排列,显示排列之后的前两条记录
@GetMapping("getAllBanner")
public R getAllBanner() {
List<CrmBanner> list = bannerService.selectAllBanner();
return R.ok().data("list", list);
}
- 因为给用于展示时我们是将banner以轮播图的形式展现,所以查询banner时不需要分页查询,直接查询全部即可
- 因为后面还要加redis,所以这里没有直接在控制层调用业务层的查询方法,而是我们自己在业务层写一个查询方法
2.在业务层接口CrmBannerService中定义抽象方法
//根据banner的id进行降序排列,显示排列之后的前两条记录
List<CrmBanner> selectAllBanner();
3.在业务层实现类CrmBannerServiceImpl中实现上一步定义的抽象方法
//根据id进行降序排列,显示排列之后的前两条记录
@Override
public List<CrmBanner> selectAllBanner() {
QueryWrapper<CrmBanner> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
//使用last方法拼接sql语句
wrapper.last("limit 2");
List<CrmBanner> list = baseMapper.selectList(null);
return list;
}
7.首页热门课程和名师(后端)
1.查询热门课程的sql语句:
课程列表可以根据view_count(浏览数量)或id或gmt_create(创建时间)进行排序。我们这里根据id进行降序排列,显示排序后的前8条记录
SELECT * FROM edu_course ORDER BY id DESC LIMIT 8
2.查询名师的sql语句:
我们这里也根据id进行降序排列,显示排序后的前4条记录
SELECT * FROM edu_teacher ORDER BY id DESC LIMIT 4
3.在service_edu模块的controller包下创建包front专一用来写前台部分,然后在front包下创建控制器IndexFrontController,并编写代码
@RestController
@RequestMapping("/eduservice/indexfront")
@CrossOrigin
public class IndexFrontController {
@Autowired
private EduCourseService courseService;
@Autowired
private EduTeacherService teacherService;
//查询前8条热门课程,查询前4条名师
@GetMapping("index")
public R index() {
//查询前8条热门课程
QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
wrapper.last("limit 8");
List<EduCourse> eduList = courseService.list(wrapper);
//查询前4条名师
QueryWrapper<EduTeacher> wrapperTeacher = new QueryWrapper<>();
wrapperTeacher.orderByDesc("id");
wrapperTeacher.last("limit 4");
List<EduTeacher> teacherList = teacherService.list(wrapperTeacher);
return R.ok().data("eduList", eduList).data("teacherList", teacherList);
}
}
为什么不将上述代码写到service_cms模块?因为这些代码是需要查讲师表和课程表的,如果想在service_cms模块操作讲师表和课程表,就需要复制讲师和课程的entity、service、mapper、xml到service_cms模块,这样太麻烦了,所以我们在service_edu模块编写上述这些代码
8.首页banner显示(前端)
8.1准备工作(封装axios)
1.我们后台的前端框架vue-admin是通过axios发送ajax请求,vue-admin框架本身就有axios组件,但是NUXT框架并没有axios组件,所以我们需要使用如下命令下载axios依赖(@0.19.2是为了和老师的版本一致)
npm install axios@0.19.2
2.后台的前端框架vue-admin中已经给我们封装好了axios
3.但是NUXT框架没有给我们封装axios,所以我们需要自己封装:
在vue-front-1010文件夹下创建文件夹utils,在utils文件夹下创建文件request.js并封装axios
import axios from 'axios' //引入axios组件
// 创建axios实例
const service = axios.create({
baseURL: 'http://localhost:9001', // api 的 base_url
timeout: 20000 // 请求超时时间
})
export default service
8.2在api中定义方法
在vue-front-1010文件夹下创建文件夹api,在api文件夹下创建banner.js文件,定义调用接口的路径
import request from '@/utils/request'
export default {
//查询前两条banner数据
getListBanner() {
return request({
url: `/educms/bannerfront/getAllBanner`,
method: 'get'
})
}
}
8.3调用api中的方法
1.在pages文件夹下的index.vue文件中引入banner.js文件
import banner from '@/api/banner'
2.定义数据模型bannerList用于存放查询到的两条banner数据(看清了嗷,这个数据模型可别写错位置了)
3.在pages文件夹下的index.vue文件中的export default {...}
中添加如下代码以调用api中的方法
created() {
//调用查询得到两条banner数据的方法
this.getBannerList()
},
methods: {
//查询得到两条banner数据
getBannerList() {
banner.getListBanner()
.then(response => {
this.bannerList = response.data.data.list
})
}
}
可能有朋友会问了,为什么前台使用NUXT框架获取后端返回数据需要通过response.data.data.list
,而后台使用vue-admin框架获取后端返回数据是通过response.data.list
?我们在前面也说过,vue-admin框架给我们做了封装
8.4将banner显示在首页
1.将下图中方框圈起来的删掉
2.将下述代码复制到上一步删除的位置
<div v-for="banner in bannerList" :key="banner.id" class="swiper-slide" style="background: #040B1B;">
<a target="_blank" :href="banner.linkUrl">
<img :src="banner.imageUrl" :alt="banner.title">
</a>
</div>
-
截图中第7行使用
v-for="banner in bannerList"
遍历bannerList数组得到每一条banner数据 -
截图中第7行的
:key="banner.id"
:因为每次遍历得到的banner都不一样,所以需要用:key="banner.id"
来做唯一标识 -
因为我们实体类CrmBanner中定义的属性是linkUrl、imageUrl、title,所以截图中第8行用的是
banner.linkUrl
第9行用的是banner.imageUrl
、banner.title
8.5测试
1.在nginx中配置8004端口
location ~ /educms/ {
proxy_pass http://localhost:8004;
}
2.将service_cms服务注册到注册中心,这样做的原因在"demo12-课程管理"的"4.4问题",具体步骤在"demo12-课程管理"的"4.3服务注册(service_vod)",这里不再演示,自行配置吧
3.重启后端、前端项目、nginx(别忘了nacos也要启动),测试效果如下
9.首页热门课程和名师(前端)
9.1在api中定义方法
在api目录下创建index.js文件,在index.js文件中调用后端接口
import request from '@/utils/request'
export default {
//查询热门课程和名师
getIndexData() {
return request({
url: `/eduservice/indexfront/index`,
method: 'get'
})
}
}
9.2调用api中的方法
1.在index.vue页面引入上一步创建的index.js文件
import index from '@/api/index'
2.定义数据模型eduList、teacherList分别用来封装热门课程、热门名师
3.在methods: {...}
中定义方法来调用api中的方法
//查询热门课程和名师
getHotCourseTeacher() {
index.getIndexData()
.then(response => {
this.eduList = response.data.data.eduList
this.teacherList = response.data.data.teacherList
})
},
9.3初始化渲染
在created方法中调用上一步定义的方法实现初始化渲染
//调用查询热门课程和名师的方法
this.getHotCourseTeacher()
9.4将热门课程和名师显示在首页
1.将下图中红框圈起来的部分删掉
2.将下述代码复制到上一步删除的位置
<li v-for="course in eduList" :key="course.id">
<div class="cc-l-wrap">
<section class="course-img">
<img
:src="course.cover"
class="img-responsive"
:alt="course.title"
>
<div class="cc-mask">
<a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a href="#" :title="course.title" class="course-title fsize18 c-333">{{course.title}}</a>
</h3>
<section class="mt10 hLh20 of">
<span class="fr jgTag bg-green" v-if="Number(course.price) === 0">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">9634人学习</i>
|
<i class="c-999 f-fA">9634评论</i>
</span>
</section>
</div>
</li>
截图中第47行代码的v-if="Number(course.price) === 0"
:课程价格是0就显示免费,否则就不显示免费
3.将下图中红框圈起来的部分删掉
4.将下述代码复制到上一步删除的位置
<li v-for="teacher in teacherList" :key="teacher.id">
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" :title="teacher.name">
<img :alt="teacher.name" :src="teacher.avatar">
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a href="/teacher/1" :title="teacher.name" class="fsize18 c-666">{{teacher.name}}</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999">{{teacher.career}}</span>
</div>
<div class="mt15 i-q-txt">
<p
class="c-999 f-fA"
>{{teacher.intro}}</p>
</div>
</section>
</li>
9.5测试
1.保存修改,测试效果如下
2.如果课程封面尺寸不一样,可能会出现排版问题,所以我们在下图所示位置添加一行代码
style="width:360px;height:185px"
10.Redis
10.1引入redis
- redis一般存什么样的数据?经常进行查询,不经常进行修改的数据
- 一个网站的首页数据是被访问次数最多的,所以我们将首页数据放到redis缓存中
10.2特点
- 基于key-value进行存储(区别于MySQL的二维表格的形式存储)
- 支持多种数据结构:string(字符串)、list(列表)、hash(哈希)、set(集合)、zset(有序集合)
- zset就是有序的set集合
- 持久化:通过内存进行存储,不过也可以存到硬盘里面去
- 为什么要通过内存进行存储呢?存到内存中读取速度快,如果存到硬盘中读取时还要进行io操作,读取速度很慢
- 支持过期时间、支持事务
笔试中经常问到的一个没有意义的问题:Redis和Memcache有什么区别?(面试中如果问到了不知道怎么回答那就说没有用过Memcache)
Redis和Memcache类似,但很大程度补偿了Memcache的不足。Redis和Memcache一样,Redis数据都是缓存在计算机内存中,不同的是,Memcache只能将数据缓存到内存中,无法自动定期写入硬盘,这就表示,一断电或重启,内存清空,数据丢失。所以Memcache的应用场景适用于缓存无需持久化的数据。而Redis不同的是它会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,实现数据的持久化
10.3在common模块添加依赖
由于redis缓存是公共应用,所以我们把依赖与配置添加到了common模块下面,现在在common模块的pom.xml中添加以下依赖
我们在"demo03-后台讲师管理模块"的"4.2.2创建common模块"的第5步已经引入过依赖了,只不过我们当时是将common-pool2依赖注释掉了,现在打开即可(别忘了舒心maven)
10.4在service_base模块添加redis配置类
在service_base模块的servicebase包下创建配置类RedisConfig并编写配置
package com.atguigu.servicebase;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@EnableCaching //开启缓存
@Configuration //配置类
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setConnectionFactory(factory);
//key序列化方式
template.setKeySerializer(redisSerializer);
//value序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
//value hashmap序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
截图中第54行的.entryTtl(Duration.ofSeconds(600)
:设置缓存中数据的过期时间,600秒后数据就没有了
10.5在接口中添加redis缓存
这里只演示改造service_cms模块首页banner接口。首页热门课程和名师后期自行比葫芦画瓢修改
10.5.1引入service_base
首先需要在service的pom.xml中引入service_base依赖
我们已经在"demo03-后台讲师管理模块"的"4.2.5在service模块中引入service-base"引入过了
10.5.2添加注解
1.@Cacheable注解:
根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上
属性值如下:
属性/方法名 | 解释 |
---|---|
value | 缓存名,必填,它指定了你的缓存存放在哪块命名空间 |
cacheName | 与value差不多,二选一即可 |
key | 可选属性,可以使用SpEL标签自定义缓存的key |
2.@CachePut注解:
使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上
属性值如下:
属性/方法名 | 解释 |
---|---|
value | 缓存名,必填,它指定了你的缓存存放在哪块命名空间 |
cacheName | 与value差不多,二选一即可 |
key | 可选属性,可以使用SpEL标签自定义缓存的key |
3.@CacheEvict注解:
使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上
属性值如下:
属性/方法名 | 解释 |
---|---|
value | 缓存名,必填,它指定了你的缓存存放在哪块命名空间 |
cacheName | 与value差不多,二选一即可 |
key | 可选属性,可以使用SpEL标签自定义缓存的key |
allEntries | 是否清空所有缓存,默认为 false。如果指定为true,则方法调用后将立即清空所有的缓存 |
beforeInvocation | 是否在方法执行前就清空,默认为 false。如果指定为true,则在方法执行前就会清空缓存 |
4.我们这里使用上述注解中的@Cacheable注解
在service_cms模块的业务层实现类CrmBannerServiceImpl的selectAllBanner方法上添加注解@Cacheable(value = "banner", key = "'selectIndexList'")
(导包时导spring包中的Cacheable,别导错包了)
10.6在service_cms中配置redis地址
在service_cms的配置文件application.properties中配置redis地址
spring.redis.host=192.168.111.100
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
截图中第25行写自己linux虚拟机的ip地址。如果我们是将redis安装在了真实的Windows系统中,那这里的ip就写127.0.0.1
10.7测试
1.先使用命令cd /usr/local/bin进入该目录,然后在该目录使用如下命令,目的是:在本地客户端(也就是linux虚拟机)连接linux虚拟机中的redis
redis-cli
2.使用如下命令查看此时redis存的有什么
keys *
3.重启后端项目,然后在地址栏访问http://localhost:3000,首页面已经展示出来了
4.再次使用命令keys *
可以看到此时redis中存了数据
banner::selectIndexList这个键名的由来:
看下图,@Cacheable注解的value属性值是banner,key属性值是selectIndexList。将banner和selectIndexList之间加两个冒号(::)就组成了存到redis中的键banner::selectIndexList
5.使用如下命令可以看到存的json数据
get banner::selectIndexList
6.去控制台中可以看到执行了sql语句,说明查询了数据库
7.使用Ctrl+F5强制刷新首页面,首页仍正常显示,去控制台看此次并没有执行执行sql语句查询banner,但banner数据仍正常显示了,说明此时是从redis缓存中取得的数据
8.首页热门课程和名师后期自行比葫芦画瓢修改
但特别注意:
①获取banner的业务逻辑我们是写在了业务层,业务层的方法返回值是List集合,所以我们直接在业务层的selectAllBanner方法上加@Cacheable注解
②但是我们获取首页热门课程和名师的业务逻辑是写在了控制层,控制层返回的是json数据,所以不能在控制器的index方法上加@Cacheable注解
我们需要将控制层的index方法中的业务逻辑转移到业务层:在业务层写两个方法分别用来查询首页热门课程和首页名师,然后在这两个方法上都加上@Cacheable注解