一、详情页面路由跳转

  应用 Vue Router 编程式导航通过 this.$router.push() 来实现路由跳转。

1、绑定查看详情事件

  修改 src/components/Course/Course.vue 文件,给课程 div 绑定查看详情事件。

<div class="courseList"><div class="detail" v-for="(course, index) in courseDetail" :key="course.id" @click="detailHandler(course.id)"><div class="head"><img :src="course.course_img" alt="" class="backImg"><!-- 背景色:行内样式优先显示 --><b class="mask" :style="{background: course.bgColor}"></b><p>{{ course.name }}</p></div>

  v-on,缩写 @ ,绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。

2、定义详情事件

methods: {// 课程详情时间操作
    detailHandler(id) {this.$router.push({name: "course.detail",params: {detailId: id,}})},

  注意:path只能和query搭配使用,name可以和params/query搭配使用,使用params传参只能使用name进行引入。

3、定义新的路由规则

  在 src/router/index.js 添加如下内容:

import CourseDetail from '@/components/Course/CourseDetail'// 配置路由规则
export default new Router({linkActiveClass: 'is-active',mode: 'history',   // 改为history模式
  routes: [// 略// 课程详情,路由:course/detail/web/3
    {path: '/course/detail/web/:detailId',   // 动态匹配name: 'course.detail',       // 路由名称component: CourseDetail      // 对应组件
    }]
})

  要把某种模式匹配到的所有路由,全部映射到同个组件。比如这里是课程详情组件,但是各个不同的课程有不同的 id,且都要用这个组件来渲染。那么可以在vue-router的路由路径中使用”动态路径参数“(dynamic segment)来实现这个效果。

  一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。于是,我们可以更新 CourseDetail 的模板,输出当前课程的 ID:

<template><div>CourseID:{{$route.params.detailId}}</div>
</template><script>export default {name: "CourseDetail",data() {return {};},};
</script>

  页面显示效果如下所示:

  

二、课程详情页面实现

1、课程详情顶部布局和样式

<template><div class="wrap"><div class="web-course-banner"><div class="container"><div class="title"><img src="../../../static/images/play.png" height="67" width="67" alt=""><h1 class="course-title">Django框架学习</h1></div><span class="course-text">Python语言下最强大优秀的WEB框架从入门到进阶</span><div class="course-list"><ul><li class="detail-item">难度:初级</li><li class="sep"></li><li class = detail-item>时长:32小时</li><li class="sep"></li><li class = detail-item>学习人数:632人</li><li class="sep"></li><li class = detail-item>评分 10.0</li></ul></div></div></div><!-- 代码略 --></div>
</template><style lang="css" scoped>.wrap{width: 100%;}.web-course-banner{width: 100%;height: 512px;background: url(../../../static/images/web-banner.1402933.png) no-repeat;background-size: 100% 100%;text-align: center;overflow: hidden;}.container{width: 1200px;margin: 182px auto 0;text-align: left;}.container img{vertical-align: middle;}.container h1{display: inline-block;font-size: 48px;color: #4a4a4a;letter-spacing: .37px;margin-left: 40px;font-family: PingFangSC-Light;font-weight: 500;line-height: 1.1;position: relative;top: 10px;}.course-text{width: 464px;display: inline-block;font-size: 22px;color: #4a4a4a;letter-spacing: .17px;line-height: 36px;margin-top: 33px;}.course-list{width: 100%;}.course-list ul{margin-top: 63px;display: flex;align-items: center;justify-content: flex-start;}.course-list ul li.detail-item{font-size: 18px;color: #4a4a4a;letter-spacing: .74px;height: 26px;padding: 0 20px;}.course-list ul li.sep{width: 2px;height: 14px;border-left: 1px solid #979797;}
</style>

  显示效果如下所示:

  

2、课程详情顶部区域数据获取

  上图中显示的数据都是写死在模板中的,需要通过axios从后端获取真实的数据信息。

(1)添加课程详情顶部接口

  在封装axios的 api.js中添加新接口:

// 课程详情顶部数据
export const coursedetailtop = (courseid)=>{return Axios.get('coursedetailtop/?courseid=${courseid}').then(res=>res.data);
};

(2)发送请求获取数据及绑定数据

<script>export default {name: 'CourseDetail',data(){return {// 声明变量存储数据coursedetailtop: {},    // 课程顶部详情数据
      }},methods: {// 发送请求获取课程详情顶部数据
      getCoursedetailtop(){this.$http.coursedetailtop(this.$route.params.detailId).then(res=>{console.log(res);if(!res.error_no){   // 取非判断没有错误this.coursedetailtop = res.data;}}).catch(err=>{console.log(err);})}},created() {this.getCoursedetailtop();}};
</script>

  查看控制台输出如下所示:

  

3、课程详情顶部数据渲染

<div class="web-course-banner"><div class="container"><div class="title"><img src="../../../static/images/play.png" height="67" width="67" alt=""><h1 class="course-title">{{coursedetailtop.name}}</h1></div><span class="course-text">{{coursedetailtop.course_solgan}}</span><div class="course-list"><ul><li class="detail-item">难度:{{coursedetailtop.level}}</li><li class="sep"></li><li class = detail-item>时长:{{coursedetailtop.hours}}小时</li><li class="sep"></li><li class = detail-item>学习人数:{{ coursedetailtop.learnnumber }}人</li><li class="sep"></li><li class = detail-item>评分 {{ coursedetailtop.course_review }}li></ul></div></div>
</div>

  显示效果如下所示:

  

4、课程详情接口适配luffy新接口

  由于luffy网站更新,原接口已经关闭,因此更新API接口(api.js):

// 课程详情顶部数据
export const coursedetailtop = (courseid)=>{return Axios.get(`course/${courseid}/top/`).then(res=>res.data);
};
// 课程概述
export const coursedetail = (courseid)=>{return Axios.get(`course/${courseid}/detail/`).then(res=>res.data);
};

  更新 CourseDetail.vue 数据绑定:

<div class="web-course-banner"><div class="container"><div class="title"><img src="../../../static/images/play.png" height="67" width="67" alt=""><h1 class="course-title">{{coursedetailtop.name}}</h1></div><span class="course-text">{{coursedetailtop.course_solgan}}</span><div class="course-list"><ul><li class="detail-item">难度:{{coursedetailtop.level}}</li><li class="sep"></li><li class = detail-item>课程总时长:{{coursedetailtop.numbers}}课时/{{coursedetailtop.hours}}小时</li><li class="sep"></li><li class = detail-item>学习人数:{{coursedetailtop.learn_number}}人</li></ul></div></div>
</div>
<div class="course-review"><ul class="review-head-wrap"><li class="head-item">课程概述</li><li class="head-item">课程章节</li><li class="head-item">用户评价({{coursedetailtop.review_number}})</li><li class="head-item">常见问题</li></ul>
</div>

  显示效果:

  

三、课程详情套餐区实现

1、更新课程详情返回数据

getCourseDetail(){this.$http.coursedetail(this.$route.params.detailId).then(res=>{console.log(res);// this.content = res.data.content;this.coursedetail = res.data;}).catch(err=>{console.log(err);})
}

2、更新课程详情套餐区模板

<!-- 课程详情 -->
<div class="course-detail"><div class="container"><!-- v-html会将元素当成HTML标签解析后输出 --><section class="course_item" v-html="content"></section></div>
</div>
<div class="course-price"><div class="container"><span>可以根据不同的学习情况购买不一样的学习套餐哦!</span><ul class="course-price-item" ><li v-for="(item, index) in coursedetail.prices" :key="item.id"><p class="price">¥{{item.price}}</p><p class="time">有效期{{item.valid_period_name}}</p></li></ul><div class="course-action"><button class="left">购买</button><button class="right">加入购物车</button></div></div>
</div>

  显示效果如下所示:

  

3、点选课程样式切换

  点击对应课程有效期,样式和颜色切换。

(1)定义li标签样式

  .course-price ul li{width: 200px;height: 112px;border: 1px solid #979797;}.course-price ul li.active{background: #00CD23;}

(2)动态绑定样式

  给li标签条件绑定active类样式。同时添加点击事件:

<ul class="course-price-item" ><li v-for="(item, index) in coursedetail.prices" :key="item.id":class="{active:index===currentIndex}" @click="priceClick(index)"><p class="price">¥{{item.price}}</p><p class="time">有效期{{item.valid_period_name}}</p></li>
</ul>

  在script中添加currentIndex原始数据和click点击事件:

<script>export default {name: 'CourseDetail',data(){return {// 声明变量存储数据coursedetailtop: {},    // 课程顶部详情数据content: "",// currentIndex: 0,   // 为0时,页面刷新默认选择了第一项currentIndex: null    // 默认不选择}},methods: {priceClick(index){this.currentIndex = index;},// 代码略},created() {this.getCoursedetailtop();this.getCourseDetail();}};
</script>

  点击效果如下所示:

  

4、通过dom修改点击项字体和颜色(不推荐)

  ref 加在普通的元素上,可用 this.ref.name 获取到的是dom元素。

<ul class="course-price-item" ><li v-for="(item, index) in coursedetail.prices" :key="item.id":class="{active:index===currentIndex}" @click="priceClick(index)"><p class="price" ref="price">¥{{item.price}}</p><p class="time" ref="time">有效期{{item.valid_period_name}}</p></li>
</ul>

  通过js来操作dom:

methods: {priceClick(index){this.currentIndex = index;this.$refs.price[index].style.color = '#fff';this.$refs.time[index].style.color = '#fff';},

5、绑定样式修改点击项字体和颜色

  传给 v-bind:class 一个对象,以动态地切换 class :

<div class="course-price"><div class="container"><span>可以根据不同的学习情况购买不一样的学习套餐哦!</span><ul class="course-price-item" ><li v-for="(item, index) in coursedetail.prices" :key="item.id":class="{active:index===currentIndex}" @click="priceClick(index)"><p class="price" :class="{active:index===currentIndex}">¥{{item.price}}</p><p class="time" :class="{active:index===currentIndex}">有效期{{item.valid_period_name}}</p></li></ul><div class="course-action"><button class="left">购买</button><button class="right">加入购物车</button></div></div>
</div>

  上面语法表示 active 这个 class 存在与否取决于数据属性 index===currentIndex 的true/false。

  添加点击项字体的 active 样式:

  .course-price ul li p.active {color: #fff;}

  如此,点击后会将点击项字体从黑色变成白色,优化显示效果。

  

四、课程购物车实现

  添加购物车时,需要判断是否点选了课程套餐,没有点选课程套餐应提示错误信息。还需要判断用户是否登录,若用户未登录需要跳转到登录页面。

1、购物车点击事件

  在购物车标签中添加点击事件:

<div class="course-action"><button class="left">购买</button><button class="right" @click="addShopCart">加入购物车</button>
</div>

  添加addShopCart方法:

<script>export default {name: 'CourseDetail',data(){return {// 声明变量存储数据coursedetailtop: {},    // 课程顶部详情数据content: "",// currentIndex: 0,   // 为0时,页面刷新默认选择了第一项currentIndex: null    // 默认不选择
      }},methods: {// 加入购物车事件
      addShopCart(){if(this.currentIndex){    // 判断当前currentIndex是否有值
} else {
}},// 代码略
  };
</script>

  这里将 currentIndex的默认值从0修改为null,这是因为如果默认为0,则默认选择了第一项,无需再提示未选中套餐。修改为 null 后,则是默认没有选择,因此可以通过 this.currentIndex 来判定当前是否选中了套餐。

2、用户未选中套餐消息提示

  在没有选择套餐时点击添加购物车提示错误消息。这里采用element组件中 Message消息提示 来实现错误提示。

methods: {// 加入购物车事件
  addShopCart(){if(this.currentIndex){    // 判断当前currentIndex是否有值
} else {// element组件错误提示this.$message({message: '您还没有选择要加入的套餐哦!',center: true        // 使用 center 属性让文字水平居中
      });}},

  Element 注册了一个$message方法用于调用,Message 可以接收一个字符串或一个 VNode 作为参数,它会被显示为正文内容。

  使用 center 属性让文字水平居中。

3、点击购物车进入登录页面

  用户点击购物车需要优先判断是否是登录用户,如果没有登录先跳转到登录页面。

(1)利用html本地存储功能实现登录用户信息保存  

  用户名、密码保存,自动登录等,可以通过设置cookie实现,第一次登录网站后在本地计算机的中写入cookie,之后再次登录此网站查看cookie中现有的值,用cookie值进行网站登录即可。但是 cookie 不适合大量数据的存储,因为它们由每个对服务器的请求来传递,这使得 cookie 速度很慢而且效率也不高。

  HTML5提供了一个此类问题比较方便的解决方案,就是localstorage。数据不是由每个服务器请求传递的,而是只有在请求时使用数据。它使在不影响网站性能的情况下存储大量数据成为可能。对于不同的网站,数据存储于不同的区域,并且一个网站只能访问其自身的数据。HTML5 使用 JavaScript 来存储和访问数据。

  

  因此可以使用 window.localStorage.getItem('token') 来判断用户是否登录。

(2)使用vue编程式导航跳转

methods: {// 加入购物车事件
  addShopCart(){if(this.currentIndex){    // 判断当前currentIndex是否有值if(window.localStorage.getItem('token')){    // 判断用户是否登录// 添加到购物车
} else {// 跳转登录页面// 使用编程式导航来跳转this.$router.push({name: 'Login',query: {// window.location 只读属性,返回一个 Location  对象,其中包含有关文档当前位置的信息return_url: window.location.href,   // 将当前页面地址作为查询参数
          }})}} else {// element组件错误提示this.$message({message: '您还没有选择要加入的套餐哦!',center: true        // 使用 center 属性让文字水平居中
      });}},

  在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push。

(3)添加Login组件和路由

  在index.js中引入Login组件并配置路由信息:

import Login from '@/components/Login/Login'Vue.use(Router)// 配置路由规则
export default new Router({linkActiveClass: 'is-active',mode: 'history',   // 改为history模式
  routes: [// 代码略
    {path: '/login',name: 'Login',component: Login     // Login 组件
    }]
})

  添加 src/components/Login/Login.vue 组件。

<template><div class="box"><img src="https://www.luffycity.com/static/img/Loginbg.3377d0c.jpg" alt=""><div class="login"><div class="login-title"><img src="https://www.luffycity.com/static/img/Logotitle.1ba5466.png" alt=""><p>帮助有志向的年轻人通过努力学习获得体面的工作和生活!</p></div><div class="login_box"><div class="title"><span>密码登录</span><span>短信登录</span></div><div class="inp"><input v-model = 'username' type="text"  placeholder="用户名 / 手机号码" class="user"><input v-model = 'password' type="password" name="" class="pwd" placeholder="密码"><div id="geetest"></div><div class="rember"><p><input type="checkbox" class="no" name="a"></input><span>记住密码</span></p><p>忘记密码</p></div><button class="login_btn">登录</button><p class="go_login" >没有账号 <span>立即注册</span></p></div></div></div></div>
</template><script>export default {name: 'Login',data(){return {username: "",password: ""}}};
</script>

  显示效果如下所示:

  

转载于:https://www.cnblogs.com/xiugeng/p/11176782.html

前端Vue项目——课程详情页面实现相关推荐

  1. luffcc项目-08-课程详情页、CKEditor富文本编辑器、课程详情页面、后台接口

    课程详情页 一.CKEditor富文本编辑器 富文本即具备丰富样式格式的文本.在运营后台,运营人员需要录入课程的相关描述,可以是包含了HTML语法格式的字符串.为了快速简单的让用户能够在页面中编辑带h ...

  2. vue项目keepAlive保持页面状态(详情页返回列表页不刷新)

    vue项目keepAlive保持页面状态(详情页返回列表页不刷新) 在vue项目中,存在从列表页跳转到详情页查看,而后又返回列表页的操作时,如果列表过长,我们往往希望从详情页返回列表页时,列表页能留在 ...

  3. 尚硅谷谷粒学院学习笔记11-- 微信支付,课程详情页面功能完善

    课程支付需求描述 课程支付说明 (1)课程分为免费课程和付费课程,如果是免费课程可以直接观看,如果是付费观看的课程,用户需下单支付后才可以观看 (2)如果是免费课程,在用户选择课程,进入到课程详情页面 ...

  4. vue项目实现详情页后退缓存之前的数据

    vue项目实现详情页后退缓存之前的数据 2019年02月19日 14:54:57 不想写代码的程序员 阅读数:244 一.需要缓存的内容: 1.后退缓存条件查询的数据 2.后退缓存分页信息 二.实现 ...

  5. 前端vue项目(使用pdf.js) pdf展示及pdf工具栏放大缩小功能实现

    前端vue项目(使用pdf.js) pdf展示及pdf工具栏放大缩小功能实现 1.vue项目pdf展示 2.pdf工具栏放大缩小功能 文章目录 前端vue项目(使用pdf.js) pdf展示及pdf工 ...

  6. 使用Docker安装的Nginx代理前端vue项目

    本篇文章主要是记录 一次使用 docker成功部署nginx之后,代理(部署)静态资源或前端vue项目,遇到的2个问题(docker安装nginx参考) 1.前置条件,防火墙关闭,开放80端口,doc ...

  7. 前端Vue项目实现CDN加速

    前端Vue项目实现CDN加速 我们在开发前端项目的时候难免会遇到请求响应慢,页面数据渲染慢,等等问题.浏览器从服务器上下载 CSS.js 和图片等文件时都要和服务器连接,而大部分服务器的带宽有限,如果 ...

  8. Windows服务器部署前端vue项目

    阿里云Windows服务器部署前端vue项目 准备工作 下载node.js(略)http://nodejs.cn/download/ 下载Nginx http://nginx.org/en/downl ...

  9. 怎么改vue项目的标题_如何动态修改Vue项目中的页面title

    前言:在项目中,我们有时候需要修改Vue项目中的页面title. 方法有两种,①如果需要动态设置页面的title,可以直接使用document.title:②可以使用router的beforeEach ...

最新文章

  1. 【机器视觉案例】(10) AI视觉搭积木,手势移动虚拟物体,附python完整代码
  2. 江西师范大学c语言程序考研,2018年江西师范大学程序设计(C语言)考研大纲
  3. pycharm安装包时各种报错,且pip无法安装
  4. 解决Nginx出现403 forbidden (13: Permission denied)报错的四种方法
  5. Laravel新建对象的方法:make resolve 辅助函数app()
  6. 【word2vec】篇三:基于Negative Sampling 的 CBOW 模型和 Skip-gram 模型
  7. 如何在 C#9 中使用顶级程序 (top-level)
  8. idea怎么调试jsp页面_解决idea的c标签错误
  9. WordPress广告管理插件Adning Advertising1.5.8汉化版
  10. python - EDA - 1 统计缺失值
  11. php descryptoserviceprovider,[WPF]C#和php实现DES加密和解密
  12. 苹果承认iPhone 12“绿屏”等问题:目前正进行调查
  13. 武汉传媒学院有计算机专业吗,武汉传媒学院比较好的专业有哪些呢?
  14. Github Star 7.2K,来自百度飞桨超级好用的OCR数据合成与半自动标注工具,强烈推荐!
  15. 反向题在测试问卷信效度_调查问卷的信效度分析
  16. word文件转换成PDF文件
  17. 2元参数matlab图,二元作用参数 - 仿真模拟 - MATLAB - 小木虫论坛-学术科研互动平台...
  18. Copy ‘XXXX‘ to effectively final temp variable
  19. 小米的200万不是这么好挣的!
  20. 基于C语言的个人所得税计税系统

热门文章

  1. 三力课堂计算机课程,打造“三力”课堂,营造幸福人生(草稿)
  2. 聊聊eureka的delta配置
  3. 《一头扎进JavaScript-基础篇》学习笔记
  4. Android各厂商自启动管理开发
  5. 基于微信平台的学生信息管理系统
  6. Keil错误 error: #5: cannot open source input file XXX / XXX.h:
  7. 关于手写笔记、电子笔记、摘录的思考
  8. 警察局抓了a,b,c,d 4名偷窃嫌疑犯,其中只有一人是小偷。审问中,a说:“我不是小偷。”b说:“c是小偷。”c说:“小偷肯定是d。”d说:“c在冤枉人。”
  9. QT时间差计算的两种方法代码
  10. unity室内渲染(白模渲染篇)