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(" ...
随机推荐
- FZU 2221—— RunningMan——————【线性规划】
Problem 2221 RunningMan Accept: 17 Submit: 52Time Limit: 1000 mSec Memory Limit : 32768 KB P ...
- Java工程路径及相对路径(转载)
3. 新建文件,默认位于工程目录new File("xxx.txt").getAbsolutePath();例如输出,D:\workspaces\workspace1\myProj ...
- C#学习笔记12
1.在使用反射时,反射可以绕过安全访问级别(private.protected)修饰的类或属性,来获取需要的信息. 2.泛型的反射:可以使用Type.ContainsGenericParameters ...
- NIOSocket Server Client
最近在看Netty框架,顺便写了一下NIO SocketChannel服务端和客户端 Server.java import java.io.IOException; import java.net.I ...
- javascript对HTML字符转义与反转义
1.背景:在项目中,经常遇到一些字符需要进行转义后才能显示到界面上,如“&”,在界面中显示的是“&”,在html中书写“&”,显示在界面的中的依然是“&”. 这时候,就 ...
- 前端之CSS——CSS选择器
一.CSS介绍 为什么需要CSS(CSS的作用)? 在没有CSS之前,我们想要修改HTML元素的样式需要为每个HTML元素单独定义样式属性,当HTML内容非常多时,就会定义很多重复的样式属性,并且修改 ...
- Django组件——分页器(paginator)
一.视图层 from django.shortcuts import render # Create your views here. from .models import Book from dj ...
- 1729 单词查找树 2000年NOI全国竞赛
1729 单词查找树 2000年NOI全国竞赛 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 在进行文法分析的 ...
- 菜鸟学习Spring——SpringMVC注解版解析不同格式的JSON串
一.概述 不同格式的JSON串传到后台来实现功能这个是我们经常要做的一件事,本篇博客就给大家介绍四种不同的JSON串传到后台后台如何用@RequestBody解析这些不同格式的JSON串的. 二.代码 ...
- C++基础--static的用法
首先,看看变量的存储: int global ; int main() { int stackStore ; int heapStore* = (int *)malloc(sizeof(int)); ...