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 相关文章推荐
表单内同名元素的控制
Nov 22 Javascript
JS去除字符串两端空格的简单实例
Dec 27 Javascript
JS 日期比较大小的简单实例
Jan 13 Javascript
详解JavaScript中的表单验证
Jun 16 Javascript
js+css实现有立体感的按钮式文字竖排菜单效果
Sep 01 Javascript
Perl Substr()函数及函数的应用
Dec 16 Javascript
javascript 网页进度条简单实例
Feb 22 Javascript
JS随机排序数组实现方法分析
Oct 11 Javascript
vue mounted 调用两次的完美解决办法
Oct 29 Javascript
vue数据初始化initState的实例详解
Apr 11 Javascript
了解JavaScript中的选择器
May 24 Javascript
微信小程序云开发如何实现数据库自动备份实现
Aug 16 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 empty函数 使用说明
2009/08/10 PHP
PHP的substr_replace将指定两位置之间的字符替换为*号
2011/05/04 PHP
自定义php类(查找/修改)xml文档
2013/03/26 PHP
php二维数组合并及去重复的方法
2015/03/04 PHP
基于PHP实现假装商品限时抢购繁忙的效果
2015/10/16 PHP
php array_walk_recursive 使用自定的函数处理数组中的每一个元素
2016/11/16 PHP
PHP面向对象程序设计OOP继承用法入门示例
2016/12/27 PHP
Joomla框架实现字符串截取的方法示例
2017/07/18 PHP
IE6与IE7中,innerHTML获取param的区别
2009/03/15 Javascript
javascript 时间比较实现代码
2009/10/28 Javascript
Javascript中的delete介绍
2012/09/02 Javascript
JS上传图片前的限制包括(jpg jpg gif及大小高宽)等
2012/12/19 Javascript
js获取html参数及向swf传递参数应用介绍
2013/02/18 Javascript
jQuery实现动画效果的简单实例
2014/01/27 Javascript
JS、DOM和JQuery之间的关系示例分析
2014/04/09 Javascript
window.location.href的用法(动态输出跳转)
2014/08/09 Javascript
基于jQuery选择器之表单对象属性筛选选择器的实例
2017/09/19 jQuery
vue之父子组件间通信实例讲解(props、$ref、$emit)
2018/05/22 Javascript
详解基于Vue cli生成的Vue项目的webpack4升级
2018/06/19 Javascript
Vue官方推荐AJAX组件axios.js使用方法详解与API
2018/10/09 Javascript
vue移动端模态框(可传参)的实现
2019/11/20 Javascript
编写简单的Python程序来判断文本的语种
2015/04/07 Python
python中字符串比较使用is、==和cmp()总结
2018/03/18 Python
python 异或加密字符串的实例
2018/10/14 Python
使用python socket分发大文件的实现方法
2019/07/08 Python
python图形用户接口实例详解
2019/12/16 Python
python软件都是免费的吗
2020/06/18 Python
如何利用XMLHTTP检测URL及探测服务器信息
2013/11/10 面试题
分厂厂长岗位职责
2013/12/29 职场文书
外国人聘用意向书
2014/04/01 职场文书
法制报告会主持词
2014/04/02 职场文书
博士生专家推荐信
2014/09/26 职场文书
志愿者服务活动总结报告
2015/05/06 职场文书
如何使用Python实现一个简易的ORM模型
2021/05/12 Python
php访问对象中的成员的实例方法
2021/11/17 PHP
详解Vue中$props、$attrs和$listeners的使用方法
2022/02/18 Vue.js