生活随笔
收集整理的這篇文章主要介紹了
Vue node.js商城-购物车模块
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?
一、渲染購物車列表頁面
新建src/views/Cart.vue
獲取cartList購物車列表數(shù)據(jù)就可以在頁面中渲染出該用戶的購物車列表數(shù)據(jù)
data(){ ??return { ?????cartList:[] // 購物車商品列表 ??} }, mounted:function(){ ??this.init(); }, methods:{ ??init(){ // 初始化商品數(shù)據(jù) ????axios.get('/users/cartList').then((response)=>{ ??????let res = response.data; ??????this.cartList = res.result; ????}) ??} }
購物車接口:server/routes/users.js
// 查詢當(dāng)前用戶的購物車數(shù)據(jù) 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
點擊刪除圖標(biāo)模態(tài)框出現(xiàn)(導(dǎo)入模態(tài)Modal.vue子組件) <!-- 刪除圖標(biāo) --> <a href="javascript:;" class="item-edit-btn" @click="delCartConfirm(item.productId)"> ????<svg class="icon icon-del"> ????????<use xlink:href="#icon-del"></use> ????</svg> </a> <!-- 模態(tài)框 --> <Modal :mdShow="modalConfirm" @close="closeModal"> ????<p slot="message">你確認(rèn)要刪除此條數(shù)據(jù)嗎?</p> ????<div slot="btnGroup"> ????????<a href="javascript:;" class="btn btn--m" @click="delCart">確認(rèn)</a> ????????<a href="javascript:;" class="btn btn--m" @click="modalConfirm = false">關(guān)閉</a> ????</div> </Modal> import Modal from '@/components/Modal.vue' // 模態(tài)框 export default { ????data(){ ????????return { ??????????productId:'', ??????????modalConfirm:false // 模態(tài)框是否顯示 ????????} ????}, ????components:{ ??????Modal ????}, ????methods:{ ??????delCartConfirm(productId){ // 點擊刪除圖標(biāo) ????????this.productId = productId; ????????this.modalConfirm = true; // 模態(tài)框顯示 ??????}, ??????closeModal(){ // 關(guān)閉模態(tài)框 ????????this.modalConfirm = false; ??????}, ??????delCart(){ // 確認(rèn)刪除此商品 ????????axios.post('/users/cartDel',{ ??????????productId:this.productId ????????}).then((response) => { ??????????let res = response.data; ??????????if(res.status = '0'){ ????????????this.modalConfirm = false; // 關(guān)閉模態(tài)框 ????????????this.init(); // 重新初始化購物車數(shù)據(jù) ??????????} ????????}) ??????} ????} }
**** 在這里發(fā)現(xiàn)一個bug,在商品列表頁點擊"加入購物車",購物車頁面新添加的商品數(shù)量和總價格是未定義。mongoose添加屬性問題
這是后端接口處理的問題,在server/routes/goods.js的加入到購物車接口中,是從mongodb的數(shù)據(jù)庫dumall的goods表根據(jù)商品id獲取對應(yīng)數(shù)據(jù),再對此商品數(shù)據(jù)添加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
//修改商品數(shù)量接口 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 ????},{ // 修改的數(shù)據(jù) ????????"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
<!--選中圖標(biāo)--> <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> <!--加減圖標(biāo)--> <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'){ // 添加商品數(shù)量 ??????????item.productNum ; ????????}else if(flag = 'minu'){ // 減少商品數(shù)量 ??????????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"); ??????????} ????????}) ??????} ????} }
?
這里出現(xiàn)一個問題,在點擊select All全選之后,顯示正常,但是刷新頁面之后全選的圖標(biāo)沒有顯示全選,因為全選的信息沒有存儲到數(shù)據(jù)庫保存,所以刷新之后就沒有了。
【解決的辦法】
用到了實時計算的computed功能,實時計算的是屬性,只不過是函數(shù)的寫法,data里面就不用在聲明了。
src/views/Cart.vue
export default { ????data(){ ????????return { ??????????// checkAllFlag:false // 控制全選 ????????} ????}, ????computed:{ // 實時計算的是屬性,只不過是函數(shù)的寫法,data里面就不用在聲明了 ??????checkAllFlag(){ // 是否全選屬性 ????????return this.checkedCount == this.cartList.length; // 勾選的商品種數(shù)=購物車商品列表的商品種數(shù)時,返回true代表全選。 ??????}, ??????checkedCount(){ // 獲取已勾選的商品種數(shù)(幾種商品已勾選) ????????var i = 0; ????????this.cartList.forEach((item)=>{ ??????????if(item.checked=='1')i ; ????????}); ????????return i; ??????} ????}, ????methods:{ ??????toggleCheckAll(){ // 全選和取消全選 ????????// this.checkAllFlag = !this.checkAllFlag; ????????// 不能使用這種寫法了,checkAllFlag是實時計算的屬性,如果true取反變成false之后,還沒來得及執(zhí)行下面的所有商品取消勾選,就實時計算了檢測到勾選的商品種數(shù)=購物車商品列表的商品種數(shù),就又變成全選了。 ????????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; ????} }
?
接下來要對價格進(jìn)行格式化,vuex官網(wǎng)github有一個對購物車將格式化的函數(shù)https://github.com/vuejs/vuex/blob/dev/examples/shopping-cart/currency.js 可以拿過來對價格格式化,在src/util/currency.js
格式化要用到過濾器:可以在src/views/Cart.vue導(dǎo)入使用局部過濾器,也可以在main.js使用全局過濾器
<span class="total-price">{{totalPrice | currency('$')}}</span> // 局部過濾器 import {currency} from '@/util/currency.js' filters:{ ??currency:currency // currency.js傳過來的本就是函數(shù) }, // 全局過濾器 import {currency} from './util/currency' Vue.filter("currency",currency);
?
更多專業(yè)前端知識,請上
【猿2048】www.mk2048.com
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎
總結(jié)
以上是生活随笔為你收集整理的Vue node.js商城-购物车模块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。