Vue node.js商城-购物车模块
一、渲染购物车列表页面
新建src/views/Cart.vue
获取cartList购物车列表数据就可以在页面中渲染出该用户的购物车列表数据
- data(){
- return {
- cartList:[] // 购物车商品列表
- }
- },
- mounted:function(){
- this.init();
- },
- methods:{
- init(){ // 初始化商品数据
- axios.get('/users/cartList').then((response)=>{
- let res = response.data;
- this.cartList = res.result;
- })
- }
- }
购物车接口:server/routes/users.js
- // 查询当前用户的购物车数据
- router.get('/cartList',function(req,res,next){
- var userId = req.cookies.userId;
- User.findOne({userId:userId},function(err,doc){
- if(err){
- res.json({
- status:'1',
- msg:err.message,
- result:''
- });
- }else{
- if(doc){
- res.json({
- status:'0',
- msg:'',
- result:doc.cartList
- })
- }
- }
- })
- })
建立路由src/router/index.js
- import Cart from '@/views/Cart' // 购物车列表
- export default
new Router({ - routes: [
- {
- path: '/cart', // 购物车列表路由
- name: 'Cart',
- component: Cart
- }
- ]
- })
二、购物车商品删除功能
购物车删除接口:server/routes/users.js
- // 购物车删除功能
- router.post('/cartDel',function(req,res,next){
- var userId = req.cookies.userId,productId = req.body.productId;
- User.update({
- userId:userId
- },{
- $pull:{
- 'cartList':{
- 'productId':productId
- }
- }
- },function(err,doc){
- if(err){
- res.json({
- status:'1',
- msg:err.message,
- result:''
- });
- }else{
- res.json({
- status:'0',
- msg:'',
- result:'suc'
- });
- }
- })
- });
src/views/Cart.vue
- 点击删除图标模态框出现(导入模态Modal.vue子组件)
- <!-- 删除图标 -->
- <a href="javascript:;" class="item-edit-btn" @click="delCartConfirm(item.productId)">
- <svg class="icon icon-del">
- <use xlink:href="#icon-del"></use>
- </svg>
- </a>
- <!-- 模态框 -->
- <Modal :mdShow="modalConfirm" @close="closeModal">
- <p slot="message">你确认要删除此条数据吗?</p>
- <div slot="btnGroup">
- <a href="javascript:;" class="btn btn--m" @click="delCart">确认</a>
- <a href="javascript:;" class="btn btn--m" @click="modalConfirm = false">关闭</a>
- </div>
- </Modal>
- import Modal from '@/components/Modal.vue' // 模态框
- export default {
- data(){
- return {
- productId:'',
- modalConfirm:false
// 模态框是否显示 - }
- },
- components:{
- Modal
- },
- methods:{
- delCartConfirm(productId){ // 点击删除图标
- this.productId = productId;
- this.modalConfirm = true; // 模态框显示
- },
- closeModal(){ // 关闭模态框
- this.modalConfirm = false;
- },
- delCart(){ // 确认删除此商品
- axios.post('/users/cartDel',{
- productId:this.productId
- }).then((response) => {
- let res = response.data;
- if(res.status = '0'){
- this.modalConfirm = false; // 关闭模态框
- this.init(); // 重新初始化购物车数据
- }
- })
- }
- }
- }
**** 在这里发现一个bug,在商品列表页点击"加入购物车",购物车页面新添加的商品数量和总价格是未定义。mongoose添加属性问题
这是后端接口处理的问题,在server/routes/goods.js的加入到购物车接口中,是从mongodb的数据库dumall的goods表根据商品id获取对应数据,再对此商品数据添加productNum和checked属性,之后再插入到users表的购物车列表中的。
属性没有添加成功,在Goods模型中添加属性,要去models/goods.js的Schema添加这两个属性。
- server/models/goods.js
- // 定义一个Schema
- var produtSchema = new Schema({
- 'productId':String,
- 'productName':String,
- 'salePrice':Number,
- 'productImage':String,
- // 添加的属性
- "checked":String,
- "productNum":Number
- })
- module.exports = mongoose.model('good',produtSchema);
重新启动express(node server/bin/www)
三、购物车商品修改功能
商品加减和商品勾选
server/routes/users.js
- //修改商品数量接口
- router.post("/cartEdit",function(req,res,next){
- var userId = req.cookies.userId,
- productId = req.body.productId,
- productNum = req.body.productNum,
- checked = req.body.checked;
- User.update({ // 查询条件
- "userId":userId,
- "cartList.productId":productId
- },{ // 修改的数据
- "cartList.$.productNum":productNum,
- "cartList.$.checked":checked
- },function(err,doc){
- if(err){
- res.json({
- status:'1',
- msg:err.message,
- result:''
- });
- }else{
- res.json({
- status:'0',
- msg:'',
- result:'suc'
- });
- }
- });
- })
src/views/Cart.vue
- <!--选中图标-->
- <a href="javascipt:;" class="checkbox-btn item-check-btn" v-bind:class="{'check':item.checked=='1'}" @click="editCart('checked',item)">
- <svg class="icon icon-ok">
- <use xlink:href="#icon-ok"></use>
- </svg>
- </a>
- <!--加减图标-->
- <a class="input-sub" @click="editCart('minu',item)">-</a>
- <a class="input-add" @click="editCart('add',item)">+</a>
- methods:{
- editCart(flag,item){
- if(flag == 'add'){ // 添加商品数量
- item.productNum++;
- }else
if(flag = 'minu'){ // 减少商品数量 - if(item.productNum <= 1){
- return;
- }
- item.productNum--;
- }else{ // 商品控制选中
- item.checked = (item.checked=='1') ? '0' : '1';
- }
- axios.post('/users/cartEdit',{
- productId:item.productId,
- productNum:item.productNum,
- checked:item.checked
- }).then((response)=>{
- let res = response.data;
- })
- }
- }
购物车全选和商品实时计算功能
- 全选和取消全选
server/routes/users.js
- //全选和取消全选
- router.post('/editCheckAll',function(req,res,next){
- var userId = req.cookies.userId,
- checkAll = req.body.checkAll?'1':'0';
- User.findOne({userId:userId},function(err,user){
- if(err){
- res.json({
- status:'1',
- msg:err.message,
- result:''
- });
- }else{
- if(user){
- user.cartList.forEach((item)=>{
- item.checked = checkAll;
- })
- user.save(function (err1,doc) {
- if(err1){
- res.json({
- status:'1',
- msg:err1,message,
- result:''
- });
- }else{
- res.json({
- status:'0',
- msg:'',
- result:'suc'
- });
- }
- })
- }
- }
- })
- })
src/views/Cart.vue
- <a href="javascipt:;" @click="toggleCheckAll">
- <span class="checkbox-btn item-check-btn" v-bind:class="{'check':checkAllFlag}">
- <svg class="icon icon-ok"><use xlink:href="#icon-ok"/></svg>
- </span>
- <span>Select all</span>
- </a>
- export default {
- data(){
- return {
- checkAllFlag:false
// 控制全选 - }
- },
- methods:{
- toggleCheckAll(){ // 全选和取消全选
- this.checkAllFlag = !this.checkAllFlag; // 取反
- this.cartList.forEach((item)=>{
- item.checked = this.checkAllFlag;
- })
- axios.post('/users/editCheckAll',{
- checkAll:this.checkAllFlag
- }).then((response)=>{
- let res = response.data;
- if(res.status=='0'){
- console.log("update suc");
- }
- })
- }
- }
- }
这里出现一个问题,在点击select All全选之后,显示正常,但是刷新页面之后全选的图标没有显示全选,因为全选的信息没有存储到数据库保存,所以刷新之后就没有了。
【解决的办法】
用到了实时计算的computed功能,实时计算的是属性,只不过是函数的写法,data里面就不用在声明了。
src/views/Cart.vue
- export default {
- data(){
- return {
- // checkAllFlag:false // 控制全选
- }
- },
- computed:{ // 实时计算的是属性,只不过是函数的写法,data里面就不用在声明了
- checkAllFlag(){ // 是否全选属性
- return
this.checkedCount == this.cartList.length; // 勾选的商品种数=购物车商品列表的商品种数时,返回true代表全选。 - },
- checkedCount(){ // 获取已勾选的商品种数(几种商品已勾选)
- var i = 0;
- this.cartList.forEach((item)=>{
- if(item.checked=='1')i++;
- });
- return i;
- }
- },
- methods:{
- toggleCheckAll(){ // 全选和取消全选
- // this.checkAllFlag = !this.checkAllFlag;
- // 不能使用这种写法了,checkAllFlag是实时计算的属性,如果true取反变成false之后,还没来得及执行下面的所有商品取消勾选,就实时计算了检测到勾选的商品种数=购物车商品列表的商品种数,就又变成全选了。
- var flag = !this.checkAllFlag; // 声明变量取代
- this.cartList.forEach((item)=>{
- item.checked = flag ?'1':'0';
- })
- axios.post('/users/editCheckAll',{
- checkAll:flag
- }).then((response)=>{
- let res = response.data;
- if(res.status=='0'){
- console.log("update suc");
- }
- })
- }
- }
- }
页面一刷新就实时计算了
- 商品实时计算功能实现
这里也要用到computed计算属性
- <div class="item-total">
- Item total: <span class="total-price">{{totalPrice}}</span>
- </div>
- computed:{
- totalPrice(){ // 总价格属性
- var money = 0;
- this.cartList.forEach((item)=>{
- if(item.checked=='1'){
- money += parseFloat(item.salePrice)*parseInt(item.productNum);
- }
- });
- return money;
- }
- }
接下来要对价格进行格式化,vuex官网github有一个对购物车将格式化的函数https://github.com/vuejs/vuex/blob/dev/examples/shopping-cart/currency.js
可以拿过来对价格格式化,在src/util/currency.js
格式化要用到过滤器:可以在src/views/Cart.vue导入使用局部过滤器,也可以在main.js使用全局过滤器
- <span class="total-price">{{totalPrice | currency('$')}}</span>
- // 局部过滤器
- import {currency} from '@/util/currency.js'
- filters:{
- currency:currency // currency.js传过来的本就是函数
- },
- // 全局过滤器
- import {currency} from './util/currency'
- Vue.filter("currency",currency);
Vue node.js商城-购物车模块的更多相关文章
- 小白学习VUE第二课:环境搭建 VUE Node.js VSCode template模板
环境搭建 VUE Node.js VSCode template模板: 首先安装node:http://www.runoob.com/nodejs/nodejs-install-setup.html ...
- 利用Node.js的Net模块实现一个命令行多人聊天室
1.net模块基本API 要使用Node.js的net模块实现一个命令行聊天室,就必须先了解NET模块的API使用.NET模块API分为两大类:Server和Socket类.工厂方法. Server类 ...
- Node.js的Formidable模块的使用
今天总结了下Node.js的Formidable模块的使用,下面做一些简要的说明. 1) 创建Formidable.IncomingForm对象 var form = new formidab ...
- Node.js入门:模块机制
CommonJS规范 早在Netscape诞生不久后,JavaScript就一直在探索本地编程的路,Rhino是其代表产物.无奈那时服务端JavaScript走的路均是参考众多服务器端语言来 ...
- Node.js的net模块
net模块提供了一个异步网络包装器,用于TCP网络编程,它包含了创建服务器和客户端的方法 创建TCP服务器 net.createServer方法 创建客户端去连接服务器 net.connect方法 简 ...
- vue+node.js+webpack开发微信公众号功能填坑——v -for循环
页面整体框架实现,实现小功能,循环出数据,整体代码是上一篇 vue+node.js+webpack开发微信公众号功能填坑--组件按需引入 修改部门代码 app.vue <yd-flexbox&g ...
- node.js中express模块创建服务器和http模块客户端发请求
首先下载express模块,命令行输入 npm install express 1.node.js中express模块创建服务端 在js代码同文件位置新建一个文件夹(www_root),里面存放网页文 ...
- node.js中ws模块创建服务端和客户端,网页WebSocket客户端
首先下载websocket模块,命令行输入 npm install ws 1.node.js中ws模块创建服务端 // 加载node上websocket模块 ws; var ws = require( ...
- node.js中net模块创建服务器和客户端(TCP)
node.js中net模块创建服务器和客户端 1.node.js中net模块创建服务器(net.createServer) // 将net模块 引入进来 var net = require(" ...
随机推荐
- BNU34058——干了这桶冰红茶!——————【递推】
干了这桶冰红茶! Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld Java class nam ...
- [转]C# - JSON详解
本文转自:http://www.cnblogs.com/QLJ1314/p/3862583.html 最近在做微信开发时用到了一些json的问题,就是把微信返回回来的一些json数据做一些处理,但是之 ...
- Array、ArrayList和List三者的区别
数组 class TestArraysClass { static void Main() { // Declare a single-dimensional array ]; // Declare ...
- Number()转换规则
转换规则: Number(): 1)如果是Boolean值,true和false将分别转换为1和0. 2)如果是数字值,只是简单的传入和返回. 3)如果是null值,返回0. 4)如果是undefin ...
- IS Decisions如何帮助企业提高安全标准
PCI DSS标准有什么要求? 简单地说,PCI DSS要求最高级别的网络安全性.这一标准如今广泛应用于需要存储.管理.传输客户(或持卡人)个人数据的行业和领域. 施行严格的访问监控措施 为了保证关键 ...
- Android NestedScrollView与RecyclerView嵌套,以及NestedScrollView不会滚动到屏幕顶部解决
①NestedScrollView与RecyclerView嵌套,导致滚动惯性消失 解决:mRecyclerView.setNestedScrollingEnabled(false); ②Nested ...
- Java中long和Long有什么区别(转)
Java的数据类型分两种:1.基本类型:long,int,byte,float,double,char2. 对象类型(类): Long,Integer,Byte,Float,Double,Char,S ...
- Java Hotspot client模式和server模式的区别
当虚拟机运行在-client模式的时候,使用的是一个代号为C1的轻量级编译器, 而-server模式启动的虚拟机采用相对重量级,代号为C2的编译器. C2比C1编译器编译的相对彻底,服务起来之后,性能 ...
- 再学UML-UML用例建模解析(一)
UML(统一建模语言)是当前软件开发中使用最为广泛的建模技术之一,通过使用UML可以构造软件系统的需求模型(用例模型).静态模型.动态模型和架构模型.UML通过图形和文字符号来描述一个系统,它是绘制软 ...
- Struts2学习-拦截器
1.新建项目user4,建立好和user3一样的目录,与之相比只是添加几个类,主要是struts.xml和action类的改变,其结果没有太大的变化 struts,xml <?xml versi ...