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(" ...
随机推荐
- DEM、DSM、DOM 名词解释
1.DEM(Digital Elevation Matrix) 数字高程矩阵. 数字高程模型(Digital Elevation Model,缩写DEM)是一定范围内规则格网点的平面坐标(X,Y)及其 ...
- bzoj 5305: [Haoi2018]苹果树
Description Solution \(n\) 个点的二叉树的方案数是 \(n!\) 证明十分显然:新加入的点占掉了 \(1\) 个位置,新加了 \(2\) 个位置,那么多出来一个位置,所以第 ...
- 弱类型dynamic与var
dynamic与var都可代替任何类型 var关键字是C# 3.0开始新增的特性,称为推断类型. 1.必须在定义时初始化 2.一但初始化完成就不能再给变量赋与初始化值类型不同的值 3.var要求是局部 ...
- Spring Cloud Ribbon负载均衡配置类放在Spring boot主类同级增加Exclude过滤后报Field config in com.cloud.web.controller.RibbonConfiguration required a bean of type 'com.netflix.client.config.IClientConfig' that could not b
环境: Spring Cloud:Finchley.M8 Spring Boot:2.0.0.RELEASE 目录结构: 可以看到代码第13行的注释,我已经在@ComponentScan注解中添加了E ...
- 如何angular过滤器进行排序???
首先定义一个json文件: 然后写HTML文件: <div id="box"> <!--第一个下拉框--> <select ng-model=&quo ...
- dhtml
网页换肤:<div> <button>red</button> <button>blue</button> <button>bl ...
- Linux下利用script命令录制并回放终端会话
Linux下利用script命令录制并回放终端会话 核心命令 script 和 scriptreplay 录制屏幕 script -t 2>timescript typescript 命令解释: ...
- ahp层次分析法软件
http://www.jz5u.com/Soft/trade/Other/58808.html 权重计算 归一化 本组当前数 - 本组最小 / 本组最大-本组最小 http://blog.csdn.n ...
- 【Spring实战】—— 13 AspectJ注解切面
前面了解了典型的AOP基于配置的使用方法,下面介绍下如何依赖于注解来实现AOP. 基于注解降低了配置文件的复杂程度,但是引入了程序间的耦合,其中的优劣待用户自己判断了. 需要注意的是,确定Aspect ...
- spring-4.3.16+xfire-spring-1.2.6版本升级
最近爆了个spring的漏洞,然后公司整体要求升级spring到最新版本,然后搞四了一大批猿人. spring-4.*的最新版本是4.3.16(稳定版) xfire-spring-1.2.6(最新版- ...