Vue.js实现开发购物车功能的方法详解


Posted in Javascript onFebruary 22, 2019

本文实例讲述了Vue.js实现开发购物车功能的方法。分享给大家供大家参考,具体如下:

购物车一般包含商品名称、单价、数量等信息,数量可以任意新增或减少,商品项也可删除,还可以支持全选或多选:

Vue.js实现开发购物车功能的方法详解

我们把这个小项目分为三个文件:

  • index.html (页面)
  • index.js (Vue 脚本)
  • style.css (样式)

1 index.js

首先在 js 中初始化 Vue 实例,整体模板如下:

var app = new Vue({
 el: '#app',
 data: {
  ...
 },
 mounted: function () {
  ...
 },
 computed: {
  ...
 },
 methods: {
  ...
 }
});

一般来说,这里的 data 来源于服务端数据,这里为了简便,所以直接定义好的数据:

data: {
  /**
   * 购物车中的商品列表
   */
  list: [
   {
    id: 1,
    name: '韩国进口海牌海苔',
    price: 39.9,
    count: 1
   },
   {
    id: 2,
    name: '印尼进口 Nabati 丽巧克(Richoco)休闲零食 巧克力味 威化饼干',
    price: 11.8,
    count: 1
   },
   {
    id: 3,
    name: '菲律宾进口 道吉草 奶油夹',
    price: 6.5,
    count: 1
   }
  ],
  //选中的商品列表,用于计算总价
  checkList: []
 }

list 用于展示 购物车中的商品列表。

checkList 用于表示勾选中的商品列表,后面,我们会利用它来计算选中商品的总价。

mounted: function () {
  //默认全选
  this.checkAll();
  this.checkAllElement(document.querySelector(".checkAll"));
}

当 mounted 时,默认全选购物车内的所有商品。

computed: {
 /**
 * 总价
 * @returns {string}
 */
 totalPrice: function () {
 var total = 0;
 for (var i = 0; i < this.checkList.length; i++) {
 var item = this.checkList[i];
 total += item.price * item.count;
 }
 return total.toLocaleString();
 }
}

在计算属性中,我们定义了总价的计算方式,它会绑定勾选的 checkList 来计算总价。之所以使用 toLocaleString 方法,是因为小数部分会自动四舍五入,而且还会以千分位表示出来,很方便哦O(∩_∩)O~

methods: {
 /**
 * 减少购买数量
 * @param index
 */
 reduceCount: function (index) {
 if (this.list[index].count === 1) return;
 this.list[index].count--;
 },
 /**
 * 增加购买数量
 * @param index
 */
 addCount: function (index) {
 this.list[index].count++;
 },
 /**
 * 移除商品
 * @param index
 */
 remove: function (index) {
 console.log("remove-index:" + index);
 this.list.splice(index, 1);
 //获取商品序号
 var id = index + 1;
    //移除实际参与计算的商品
 var $checkList = this.checkList;
 for (var i = 0; i < $checkList.length; i++) {
 var item = $checkList[i];
 if (item.id == id) {
 $checkList.splice(i, 1);
 }
 }
 },
 /**
 * 全选或全不选
 * @param event
 */
 checkAllOrNot: function (event) {
 if (event.target.checked) {//全选
 this.checkAll();
 console.log("checkList:" + this.checkList);
 } else { // 全不选
 console.log("全不选");
 this.checkInItems('noCheckAll');
 this.checkList.splice(0);//清空数组
 }
 },
 /**
 * 全选
 */
 checkAll: function () {
 console.log("全选");
 this.checkInItems('checkAll');
 this.checkList = this.list.concat();//复制商品列表
 },
 /**
 * 全选或全不选
 * @param type checkAll:全选;其他:全不选
 */
 checkInItems: function (type) {
 var items = document.querySelectorAll('.checkItem');
 for (var i = 0; i < items.length; i++) {
 var item = items[i];
 if (type === 'checkAll') {
 item.checked = true;
 } else {
 item.checked = false;
 }
 }
 },
 /**
 * 勾选或不勾选
 */
 checkItem: function (event, index) {
 console.log("checkItem");
 var element = event.target;
 var $allCheck = document.querySelector(".checkAll");
 if (element.checked) {//勾选,加入已选择列表
 this.checkList.push(this.list[index]);
 this.checkAllElement($allCheck);
 } else {//不勾选,从已选择列表中去除
 this.checkList.splice(index, 1);
 $allCheck.checked = false;
 }
 },
 /**
 * 勾选全选框
 * @param element
 */
 checkAllElement: function (element) {
 //如果所有的商品都已被勾选,则勾选全选框
 if (this.checkList.length == this.list.length) {
 element.checked = true;
 }
 }
}

在 methods 中,我们定义了以下功能方法:

减少与增加购买数量。在减少购买数量方法中,我们对当前所对应商品的数量进行了二次确认,让代码变得更加健壮(HTML 模板可能被修改,button 被替换为 div 或者 span,那么 disabled 样式就变得无效啦)。

移除某件商品。因为购物车中的商品列表与实际勾选的商品列表数量上有可能存在差异,所以我们必须通过找到商品 ID 再进行删除。

勾选相关操作(全选、全不选、单选、单不选等)

2 style.css

[v-cloak] {
 display: none;
}
table {
 border: 1px solid #e9e9e9;
 border-collapse: collapse;
 border-spacing: 0;
 empty-cells: show;
}
th {
 font: bold 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
 color: #4f6b72;
 border-right: 1px solid #C1DAD7;
 border-bottom: 1px solid #C1DAD7;
 border-top: 1px solid #C1DAD7;
 letter-spacing: 2px;
 text-transform: uppercase;
 text-align: left;
 padding: 6px 6px 6px 12px;
 background: #CAE8EA;
}
td {
 border-right: 1px solid #C1DAD7;
 border-bottom: 1px solid #C1DAD7;
 background: #fff;
 font-size:14px;
 padding: 6px 6px 6px 12px;
 color: #4f6b72;
}

这里定义了 v-cloak 样式,用于解决网络慢时的闪屏问题。还定义了表格的相关样式。

3 index.html

接着在 index.html 中引入 Vue 脚本与样式文件。基本模板如下:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>购物车</title>
 <link rel="stylesheet" type="text/css" href="style.css" rel="external nofollow" >
</head>
<body>
<div id="app" v-cloak>
 ...
</div>
<script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
<script src="index.js"></script>
</body>
</html>

因为有可能购物车中的商品被全部删除,所以我们在此加了判断,如果列表为空,则给出友好提示:

<template v-if="list.length">
 ...
</template>
<!--当购物车为空时,则提示-->
<div v-else>购物车内暂时没有商品</div>

接着用 table 来展示购物车内的商品列表:

<table>
 <thead>
 <tr>
 <th><input id="checkAll" type="checkbox" class="checkAll" @click="checkAllOrNot($event)"></th>
 <th>序号</th>
 <th>商品</th>
 <th>单价</th>
 <th>数量</th>
 <th>操作</th>
 </tr>
 </thead>
 <tbody>
 <tr v-for="(item,index) in list">
 <td><input type="checkbox" class="checkItem" @click="checkItem($event,index)"></td>
 <td>{{index+1}}</td>
 <td>{{item.name}}</td>
 <td>{{item.price}}</td>
 <td>
 <button @click="reduceCount(index)" :disabled="item.count===1">-</button>
 {{item.count}}
 <button @click="addCount(index)">+</button>
 </td>
 <td>
 <button @click="remove(index)">删除</button>
 </td>
 </tr>
 </tbody>
</table>
<div>总价:¥{{totalPrice}}</div>

使用 v-for 指令,循环迭代出商品列表。

表格内的每一个勾选框与按钮都绑定了相应的事件。全选框与每一行的勾选框还传入了原生 DOM 事件 $event,用于获取当前所操作的元素。

*这里对减少商品数量的按钮进行了判断,当相应商品的数量只剩下一个时,绑定 disabled 样式,让它变成不可用。

4 演示

Vue.js实现开发购物车功能的方法详解

本文jsfiddle示例DEMO地址:https://jsfiddle.net/deniro/hvq1y72o/

希望本文所述对大家vue.js程序设计有所帮助。

Javascript 相关文章推荐
jQuery ready函数滥用分析
Feb 16 Javascript
分享纯手写漂亮的表单验证
Nov 19 Javascript
jQuery数据类型小结(14个)
Jan 08 Javascript
下雪了 javascript实现雪花飞舞
Aug 02 Javascript
javascript创建含数字字母的随机字符串方法总结
Aug 01 Javascript
详解vue父子模版嵌套案例
Mar 04 Javascript
JS控件bootstrap suggest plugin使用方法详解
Mar 25 Javascript
jQuery实现可编辑表格并生成json结果(实例代码)
Jul 19 jQuery
详解vue.js之props传递参数
Dec 12 Javascript
Angular通过指令动态添加组件问题
Jul 09 Javascript
解决Layui数据表格的宽高问题
Sep 28 Javascript
浅谈微信小程序列表埋点曝光指南
Oct 15 Javascript
vue组件之间通信方式实例总结【8种方式】
Feb 22 #Javascript
vue2.0中set添加属性后视图不能更新的解决办法
Feb 22 #Javascript
浅谈Node框架接入ELK实践总结
Feb 22 #Javascript
vue工程全局设置ajax的等待动效的方法
Feb 22 #Javascript
JavaScript数据结构与算法之检索算法示例【二分查找法、计算重复次数】
Feb 22 #Javascript
详解基于iview-ui的导航栏路径(面包屑)配置
Feb 22 #Javascript
JavaScript数据结构与算法之检索算法实例分析【顺序查找、最大最小值、自组织查询】
Feb 22 #Javascript
You might like
PHP __autoload()方法真的影响性能吗?
2012/03/30 PHP
jquery中的mouseleave和mouseout的区别 模仿下拉框效果
2012/02/07 Javascript
深入理解JavaScript系列(14) 作用域链介绍(Scope Chain)
2012/04/12 Javascript
javascript中数组array及string的方法总结
2014/11/28 Javascript
关于Javascript加载执行优化的研究报告
2014/12/16 Javascript
在JavaScript中call()与apply()区别
2016/01/22 Javascript
Javascript基础教程之比较null和undefined值
2016/05/16 Javascript
完美解决IE不支持Data.parse()的问题
2016/11/24 Javascript
AngularJS中$apply方法和$watch方法用法总结
2016/12/13 Javascript
使用watch在微信小程序中实现全局状态共享
2019/06/03 Javascript
JS 5种遍历对象的方式
2020/06/16 Javascript
vue中activated的用法
2021/01/03 Vue.js
Django中利用filter与simple_tag为前端自定义函数的实现方法
2017/06/15 Python
python with提前退出遇到的坑与解决方案
2018/01/05 Python
python实现日常记账本小程序
2018/03/10 Python
Python解决八皇后问题示例
2018/04/22 Python
python批量修改图片后缀的方法(png到jpg)
2018/10/25 Python
python实现控制COM口的示例
2019/07/03 Python
在Python中COM口的调用方法
2019/07/03 Python
Django框架安装方法图文详解
2019/11/04 Python
TensorFlow基本的常量、变量和运算操作详解
2020/02/03 Python
python实现打砖块游戏
2020/02/25 Python
浅谈matplotlib.pyplot与axes的关系
2020/03/06 Python
基于Python爬取fofa网页端数据过程解析
2020/07/13 Python
python和C++共享内存传输图像的示例
2020/10/27 Python
CSS3 please 跨浏览器的CSS3产生器
2010/03/14 HTML / CSS
使用CSS3配合IE滤镜实现渐变和投影的效果
2015/09/06 HTML / CSS
教师实习期自我鉴定
2013/10/06 职场文书
军训心得体会
2013/12/31 职场文书
银行员工辞职信范文
2014/01/20 职场文书
民用住房租房协议书
2014/10/29 职场文书
消防隐患整改通知书
2015/04/22 职场文书
办公经费申请报告
2015/05/15 职场文书
《钓鱼的启示》教学反思
2016/02/18 职场文书
SQL注入的实现以及防范示例详解
2021/06/02 MySQL
配置nginx负载均衡
2022/05/06 Servers