日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

Vue node.js商城-购物车模块

發(fā)布時間:2023/12/2 vue 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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ù)庫dumallgoods表根據(jù)商品id獲取對應(yīng)數(shù)據(jù),再對此商品數(shù)據(jù)添加productNumchecked屬性,之后再插入到users表的購物車列表中的。

    屬性沒有添加成功,在Goods模型中添加屬性,要去models/goods.jsSchema添加這兩個屬性。

  • 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");
  • ??????????}
  • ????????})
  • ??????}
  • ????}
  • }
  • ?

    頁面一刷新就實時計算了

    • 商品實時計算功能實現(xiàn)

    這里也要用到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)容還不錯,歡迎將生活随笔推薦給好友。