一、加入购物车的两种策略

1、加入购物车接口

  在 src/restful/api.js 中写入添加购物车接口:

// 加入购物车的接口
export const shopCart = (params) => {
return Axios.post('user/shop_cart/create/', params).then(res=>res.data)
};

2、添加Axios的请求拦截器

  Axios 的拦截器:在请求或响应被 then 或 catch 处理前拦截它们,说明文档:Axios使用说明。模板如下所示:

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}); // 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});

  在项目 src/restful/api.js 中添加请求拦截器:

import Axios from 'axios'  // 导入axios
Axios.defaults.baseURL = 'https://www.luffycity.com/api/v1/'; // 设置公共url // 添加请求拦截器
Axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
if (localStorage.getItem('access_token')){
// 配置的默认值/defaults
// Axios.defaults.headers.common['Authorization'] = localStorage.getItem('access_token');
console.log(config.headers);
config.headers.Authorization = localStorage.getItem('access_token');
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});

  查看控制台 config.headers 中包含的信息:

  

3、改写CouseDetail页面中购物车事件

(1)课程信息获取

  添加购物车首先要获取当前课程信息。

<script>
export default {
name: 'CourseDetail',
data(){
return {
// 声明变量存储数据
coursedetailtop: {}, // 课程顶部详情数据
content: "",
// currentIndex: 0, // 为0时,页面刷新默认选择了第一项
currentIndex: null, // 默认不选择
prices: []
}
},
methods: {
// 加入购物车事件
addShopCart(){
if(this.currentIndex){ // 判断当前currentIndex是否有值
if(window.localStorage.getItem('access_token')){ // 判断用户是否登录
// 添加到购物车
alert('买吧');
let course = {
courseId: this.$route.params.detailId, // 课程id
validPeriodId: this.prices[this.currentIndex].valid_period,
};
console.log(course);
// this.$http.shopCart(); } else {
// 跳转登录页面
// 使用编程式导航来跳转// 代码略
</script>

  在控制台查看打印的course对象:

  

(2)添加购物车事件

methods: {
// 加入购物车事件
addShopCart(){
if(this.currentIndex){ // 判断当前currentIndex是否有值
if(window.localStorage.getItem('access_token')){ // 判断用户是否登录
// 添加到购物车
alert('买吧');
let course = {
courseId: this.$route.params.detailId, // 课程id
validPeriodId: this.prices[this.currentIndex].valid_period,
};
console.log(course);
this.$http.shopCart(course)
.then(res=>{
console.log("当前添加是否成功", res);
})
.catch(err=>{
console.log('添加失败', err);
}) } else {
// 跳转登录页面
// 使用编程式导航来跳转
this.$router.push({
name: 'Login',
query: {
// window.location 只读属性,返回一个 Location 对象,其中包含有关文档当前位置的信息
return_url: window.location.href, // 将当前页面地址作为查询参数
}
})
}
} else {
// element组件错误提示
this.$message({
message: '您还没有选择要加入的套餐哦!',
center: true // 使用 center 属性让文字水平居中
});
}
},

  点击添加购物车显示效果如下:

  

  购物车没有当前课程时,点击添加后,信息为error_no:0,显示 “添加成功”。

  如果购物车已经有了当前课程,选择一个套餐后点击添加,信息为error_no:10,显示“购物车中该课程已更新成功”。

二、购物车页面实现

1、使用elementui显示加入购物车提示

  elementui中Message消息提示:常用于主动操作后的反馈提示。这里引入基础用法,从顶部出现,3秒后自动消失。

methods: {
// 加入购物车事件
addShopCart(){
if(this.prices[this.currentIndex]){ // 不能直接使用this.currentIndex,因为第一个值为0
if(window.localStorage.getItem('access_token')){ // 判断用户是否登录
// 添加到购物车
alert('买吧');
let course = {
courseId: this.$route.params.detailId, // 课程id
validPeriodId: this.prices[this.currentIndex].valid_period,
};
console.log(course);
this.$http.shopCart(course)
.then(res=>{
console.log("当前添加是否成功", res);
if(res.error_no===0){
this.$message('购物车' + res.data.status); // elementui提示框
}
if(res.error_no===10){
this.$message(res.msg);
}
})
.catch(err=>{
console.log('添加失败', err);
}) } else {
// 跳转登录页面
// 使用编程式导航来跳转
this.$router.push({
name: 'Login',
query: {
// window.location 只读属性,返回一个 Location 对象,其中包含有关文档当前位置的信息
return_url: window.location.href, // 将当前页面地址作为查询参数
}
})
}
} else {
// element组件错误提示
this.$message({
message: '您还没有选择要加入的套餐哦!',
center: true // 使用 center 属性让文字水平居中
});
}
},

  选择套餐后点击“加入购物车”,显示如下信息:

  

2、购物车组件及路由

(1)index.js中添加购物车组件路由

// 代码略
import Cart from '@/components/Cart/Cart' Vue.use(Router); // 配置路由规则
export default new Router({
linkActiveClass: 'is-active',
mode: 'history', // 改为history模式
routes: [
// 代码略
// 购物车页面
{
path: '/purchase/shopping_cart',
name: 'purchase.shop',
component: Cart
}
]
})

(2)创建购物车组件

  创建购物车文件夹及文件:src/components/Cart/Cart.vue

  使用elementUI中Table表格模板来构筑组件页面结构。Table表格可用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。

  实现多选非常简单: 手动添加一个el-table-column,设type属性为selection即可。每个 el-table-column 组件中有 template,可以定义当前内容的展示。

  scope.row相当于获取了数组中的每一条数据。

<template>
<div class="shopping-cart-wrap">
<h3 class="shopping-cart-tit">我的购物车<small>共1门课程</small></h3>
<div class="row">
<el-table
ref="multipleTable"
:data="shopCartList"
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
label="日期"
width="120">
<template slot-scope="scope">{{ scope.row.date }}</template>
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="120">
</el-table-column>
<el-table-column
prop="address"
label="地址"
show-overflow-tooltip>
</el-table-column>
</el-table>
</div>
<div class="total">
<el-button type="primary">去结算</el-button>
<h3>总计: ¥399</h3>
</div>
</div>
</template> <script>
export default {
name:'Cart',
data(){
return { }
},
};
</script>

(3)页首按钮跳转购物车

<div class="nav-right" v-if="userInfo.access_token" @mouseenter="enterHandler" @mouseleave="leaveHandler">
<span class = 'el-dropdown-link'>学习中心</span>
<span class="user">{{userInfo.username}}</span>
<img :src="userInfo.avatar" alt="">
<ul class="my_account" v-show="isShow">
<li>我的账户<i>></i></li>
<li>我的订单<i>></i></li>
<li>我的优惠券<i>></i></li>
<li>我的消息<span class="msg">({{userInfo.notice_num}})</span><i>></i></li>
<li @click="shopCartInfo">购物车<span class="count">({{userInfo.shop_cart_num}})</span></li>
<li>退出<i>></i></li>
</ul>
</div> methods: {
shopCartInfo(){
// 跳转到购物车路由
this.$router.push({
name: 'purchase.shop'
})
},

三、购物车页面数据展示

1、获取购物车页面接口

  在 src/restful/api.js 添加如下信息:

// 购物车数据
export const shopCartList = () => {
return Axios.get('user/shop_cart/list/').then(res=>res.data);
};

2、car组件发送请求

  修改Cart.vue组件。

  handleSelectionChange(val) { this.multipleSelection = val; }  其中,val 为选中数据的集合。通过this.multipleSelection.prop字段 取得每一个选项的值,prop字段就是表格里面子项的prop值。this.multipleSelection.length为选择了多少项。

<script>
export default {
name:'Cart',
data(){
return {
multipleSelection: [], // 存放选中的当前数据
shopCartList: [],
}
},
methods: {
getShopCartList(){
this.$http.shopCartList()
.then(res=>{
console.log(res);
if(res.error_no === 0){
this.shopCartList = res.data.myShopCart;
}
})
.catch(err=>{
console.log(err);
})
},
handleSelectionChange(val){ // 处理点选
this.multipleSelection = val;
}
},
created() {
this.getShopCartList();
}
};
</script> 

3、将数据绑定到template中

(1)页面构建和数据绑定

  javascript:void(0) 中最关键的是 void 关键字, void 是 JavaScript 中非常重要的关键字,该操作符指定要计算一个表达式但是不返回值。

  有效期栏目中,添加select组件,点选到对应的有效期。HTML <select> 元素表示一个控件,提供一个选项菜单。菜单内的选项为<option> , 可以由 <optgroup> 元素分组。选项可以被用户预先选择。

<div class="row">
<el-table
ref="multipleTable"
:data="shopCartList"
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
label="课程"
width="555">
<template slot-scope="scope">
<img :src="scope.row.courseImg" alt="">
<a href="javascript:void(0);">{{scope.row.courseName}}</a>
</template>
</el-table-column>
<el-table-column
prop="name"
label="有效期"
width="212">
<template slot-scope="scope">
<select>
<option v-for="(item, index) in scope.row.validPeriodChoices"
:value="item.validPeriodId" :key="index">
有效期: {{item.validPeriodId}}
</option>
</select>
</template>
</el-table-column>
<el-table-column
prop="address"
label="单价"
show-overflow-tooltip>
<template slot-scope="scope">
¥{{scope.row.coursePrice}}
</template>
</el-table-column>
</el-table>
</div>

  显示效果如下所示:

  

(2)v-model默认选定selected

  在select中,当v-model的值等于option中的value,则默认选中。

<el-table-column
prop="name"
label="有效期"
width="212">
<template slot-scope="scope">
<select v-model="scope.row.validPeriodId">
<option v-for="(item, index) in scope.row.validPeriodChoices"
:value="item.validPeriodId" :key="index">
有效期: {{item.validPeriodId}}
</option>
</select>
</template>
</el-table-column>

四、购物车页面数据响应

1、添加删除按钮

(1)表格中添加操作列

  @click.native.prevent:调用组件原生的click事件,阻止默认事件发生。在封装好的组件上使用,所以要加上.native才能click。

  prevent就相当于 event.preventDefault():如果此事件没有被显式处理,那么它默认的动作也不要做(因为默认是要做的)。此事件还是继续传播,除非碰到事件侦听器调用stopPropagation() 或stopImmediatePropagation(),才停止传播。

<el-table>
<!--代码略-->
<el-table-column
fixed="right"
label="操作"
width="100">
<template slot-scope="scope">
<el-button @click.native.prevent="deleteRow(scope.$index, shopCartList)" type="text" size="small">
删除
</el-button>
<el-button type="text" size="small">编辑</el-button>
</template>
</el-table-column>
</el-table>

(2)删除课程操作

  未完成

methods: {
// 删除课程
deleteRow(index, rows){
console.log(index);
console.log(rows);
rows.splice(index, 1); },

2、监控课程总价变化

  使用computed实时监控鼠标点选课程总价变化。

computed: {
totalPrice(){
let total_price = 0;
this.multipleSelection.forEach((item,index)=>{ // 遍历数组中对象的价格
// parseInt() 方法用于将字符串参数作为有符号的十进制整数进行解析
total_price += parseInt(item.coursePrice) // 将获取的价格相加
});
return total_price;
}
},

  显示效果如下所示

  

前端Vue项目——购物车页面的更多相关文章

  1. 前端Vue项目——登录页面实现

    一.geetest滑动验证 geetest官方文档地址:https://docs.geetest.com/ 产品——极速验证:基于深度学习的人机识别应用.极验「行为验证」是一项可以帮助你的网站与APP ...

  2. 团队开发前端VUE项目代码规范

    团队开发前端VUE项目代码规范 2018年09月22日 20:18:11 我的小英短 阅读数 1658   一.规范目的: 统一编码风格,命名规范,注释要求,在团队协作中输出可读性强,易维护,风格一致 ...

  3. vue项目刷新页面,使数据不丢失(sessionStorage、localStorage、cookie)

    vue项目刷新页面时,存储在vuex中的数据会丢失,把他们存到stroage中可以保证不丢失.

  4. 前端Vue项目——首页/课程页面开发及Axios请求

    一.首页轮播图 1.elementUI走马灯 elementUI中 Carousel 走马灯,可以在有限空间内,循环播放同一类型的图片.文字等内容. 这里使用指示器样式,可以将指示器的显示位置设置在容 ...

  5. VUE项目实现页面跳转

    打开一个VUE项目,目录结构是这样的: 如现在有两个页面aaa和HelloWorld,路由配置在index.js中: import Vue from 'vue' import Router from ...

  6. 前端Vue项目——课程详情页面实现

    一.详情页面路由跳转 应用 Vue Router 编程式导航通过 this.$router.push() 来实现路由跳转. 1.绑定查看详情事件 修改 src/components/Course/Co ...

  7. 前端vue项目部署到tomcat,一刷新报错404解决方法

    公司前端写的后台部署到tomcat webapps目录下后,无法进行刷新,一刷新就会报错404,自动跳的404页面.在网上查了下,官方说是HTML5 History 模式引发的问题,但是解决方案中,并 ...

  8. 前端 | Vue 路由返回恢复页面状态

    需求场景:首页搜索内容,点击跳转至详情页,页面后退返回主页,保留搜索结果. 方案:路由参数:路由守卫 需求描述 在使用 Vue 开发前端的时候遇到一个场景:在首页进行一些数据搜索,点击搜索结果进入详情 ...

  9. 前端vue项目-关于下载文件pdf/excel(三)

    最近在做一些需求,需要下载一些文件信息,最频繁的就是下载excel文件到本地了 看过了很多方法,做个整理吧哈哈哈哈 参考的文章链接: https://www.cnblogs.com/jiangweic ...

随机推荐

  1. MySQL select from where multiple conditions

    Maybe one of the most used MySQL commands is SELECT, that is the way to stract the information from ...

  2. window10下pytorch和torchvision CPU版本安装

    1.环境 python3.5 Anaconda 4.2.0 2.pytorch安装 pip3 install https://download.pytorch.org/whl/cpu/torch-1. ...

  3. IT兄弟连 Java语法教程 流程控制语句 分支结构语句1

    不论哪一种编程语言,都会提供两种基本的流程控制结构:分支结构和循环结构.其中分支结构用于实现根据条件来选择性地执行某段代码,循环结构则用于实现根据循环条件重复执行某段代码.Java同样提供了这两种流程 ...

  4. pixijs shader 实现图片波浪效果

    const app = new PIXI.Application({ transparent: true }); document.body.appendChild(app.view); // Cre ...

  5. 策略路由PBR(不含track)

    策略路由:是一种依据用户制定的策略进行路由选择的机制.(公义)在特定数据进入路由表前,对其进行操控的方式.(本人定义) 根据作用对象的不同,策略路由可分为本地策略路由和接口策略路由: · 本地策略路由 ...

  6. linux的ls命令详解

    概述 Linux ls命令用于显示指定工作目录下之内容(列出目前工作目录所含之文件及子目录). 语法 ls [-alrtAFR] [name...] 参数 -a 显示所有文件及目录 (ls内定将文件名 ...

  7. Ganglia+Nagios监控系统

    第1章 简介 ganglia是一款为HPC(高性能计算) 集群设计的可扩展性 的分布式监控系统,它可以监视和显示集群中节点的各种状态信息,他由运行在各个节点上的gmond守护进程来采集 CPU.内存. ...

  8. PHP odbc_errormsg ODBC 函数

    定义和用法 odbc_errormsg - 获取最后一条错误消息 语法 odbc_errormsg ( [ resource $connection_id ] ) 返回包含最后一个ODBC错误消息的字 ...

  9. JS基础语法---练习:交换两个变量的值

    * JavaScript简称为JS * JavaScript是什么?     * 是一门脚本语言:不需要编译,直接运行     * 是一门解释性的语言:遇到一样代码就解释一行代码     * C#语言 ...

  10. Node.js实现热加载

    不管是node.js原生开发,还是借助express,kora等框架开发node.js的情况下,在对代码做出更新后,都是需要重启已生效我们的文件的. 本文记录一次在原生node.js开发的时候,为项目 ...