中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

焦作網(wǎng)站建設兼職網(wǎng)絡推廣公司哪家做得好

焦作網(wǎng)站建設兼職,網(wǎng)絡推廣公司哪家做得好,怎么做代刷網(wǎng)站,廣州地區(qū)網(wǎng)站建設文章目錄29.加入購物車操作(難點)29.1加入購物車按鈕29.2addCartSuce29.3購物車29.3.1 向服務器發(fā)送ajax請求,獲取購物車數(shù)據(jù)29.3.2UUID臨時游客身份29.3.3動態(tài)展示購物車29.4修改購物車產(chǎn)品的數(shù)量(需要發(fā)請求:參數(shù)理解…

在這里插入圖片描述

文章目錄

    • 29.加入購物車操作(難點)
      • 29.1加入購物車按鈕
      • 29.2addCartSuce
      • 29.3購物車
        • 29.3.1 向服務器發(fā)送ajax請求,獲取購物車數(shù)據(jù)
        • 29.3.2UUID臨時游客身份
        • 29.3.3動態(tài)展示購物車
      • 29.4修改購物車產(chǎn)品的數(shù)量(需要發(fā)請求:參數(shù)理解)
      • 29.5刪除某一產(chǎn)品
      • 29.6修改產(chǎn)品狀態(tài)
      • 29.7刪除全部選中的商品
      • 29.8全選操作
  • 本人其他相關(guān)文章鏈接

29.加入購物車操作(難點)

重難點說明

  1. 用戶臨時ID的處理

  2. 購物車數(shù)據(jù)的管理(復雜)

  3. 不使用v-model監(jiān)控用戶輸入

  4. async / await / Promise.all() 的使用

思路:

  1. 加入購物車按鈕

    • 路由跳轉(zhuǎn)之前發(fā)請求

    • 成功路由跳轉(zhuǎn)與參數(shù)傳遞

    • 失敗提示失敗信息

  2. addCartSuce

    • 查看詳情
    • 查看購物車
  3. 購物車

    • 購物車靜態(tài)組件-需要修改樣式結(jié)構(gòu)(刪除第三項并調(diào)整css讓各個項目對齊,比例為:15 35 10 17 10 13)
    • 向服務器發(fā)送ajax請求,獲取購物車數(shù)據(jù)
    • UUID臨時游客身份
    • 動態(tài)展示購物車
  4. 修改購物車產(chǎn)品的數(shù)量(需要發(fā)請求:參數(shù)理解)

  5. 刪除某一產(chǎn)品

  6. 修改產(chǎn)品狀態(tài)

  7. 刪除全部選中的商品

  8. 全選操作

29.1加入購物車按鈕

加入購物車按鈕

  • 路由跳轉(zhuǎn)之前發(fā)請求

  • 成功路由跳轉(zhuǎn)與參數(shù)傳遞

  • 失敗提示失敗信息

修改代碼:

src/pages/Detail/index.vue

<a href="javascript:" @click="addOrUpdateShopCar">加入購物車</a>methods: {//加入購物車async addOrUpdateShopCar() {//1:在點擊加入購物車這個按鈕的時候,做的第一件事情,將參數(shù)帶給服務器(發(fā)請求),通知服務器加入購車的產(chǎn)品是誰//this.$store.dispatch('addOrUpdateShopCart'),說白了,它是在調(diào)用vuex倉庫中的這個addOrUpdateShopCart函數(shù)。//2:你需要知道這次請求成功還是失敗,如果成功進行路由跳轉(zhuǎn),如果失敗,需要給用戶提示try {//成功await this.$store.dispatch("addOrUpdateShopCar", {skuId: this.$route.params.skuId, skuNum: this.skuNum});//3:進行路由跳轉(zhuǎn)//4:在路由跳轉(zhuǎn)的時候還需要將產(chǎn)品的信息帶給下一級的路由組件//一些簡單的數(shù)據(jù)skuNum,通過query形式給路由組件傳遞過去//產(chǎn)品信息的數(shù)據(jù)【比較復雜:skuInfo】,通過會話存儲(不持久化,會話結(jié)束數(shù)據(jù)在消失)//本地存儲|會話存儲,一般存儲的是字符串sessionStorage.setItem("SKUINFO", JSON.stringify(this.skuInfo))this.$router.push({name: "addCartSuccess", query:{skuNum: this.skuNum}})} catch (error) {//失敗alert(error.message);}}
}

src/api/index.js

//將產(chǎn)品添加到購物車中(獲取更新某一個產(chǎn)品的個數(shù))
// /api/cart/addToCart/{ skuId }/{ skuNum }  POST
export const addOrUpdateShopCar = (skuId, skuNum)=>requests({url:`/cart/addToCart/${skuId}/${skuNum}`, method:"post"});

src/store/detail/index.js

import {getGoodsInfo, addOrUpdateShopCar} from "@/api";const actions = {//加入購物車的||修改某一個產(chǎn)品的個數(shù),注意一定要用解構(gòu)方法解構(gòu)形參對象,不能寫成接收兩個形參形式,那樣會報錯接口調(diào)不通async addOrUpdateShopCar(context, {skuId, skuNum}) {//發(fā)請求:前端帶一些參數(shù)給服務器【需要存儲這些數(shù)據(jù)】,存儲成功了,沒有給返回數(shù)據(jù)//不需要在三連環(huán)(倉庫存儲數(shù)據(jù)了)//注意:async函數(shù)執(zhí)行返回的結(jié)果一定是一個promise【要么成功,要么失敗】let response = await addOrUpdateShopCar(skuId, skuNum);if (response.code == 200) {//返回的是成功的標記return "OK";} else {//返回的是失敗的標記return Promise.reject(new Error("fail"))}},
}

注意點1:

問題:加入購物車路由跳轉(zhuǎn)跟普通的路由跳轉(zhuǎn)不一樣,不一樣在哪里?

答案:因為加入購物車功能得先調(diào)接口保存加入購物車的數(shù)據(jù),然后再跳轉(zhuǎn)路由。而普通的路由跳轉(zhuǎn)直接跳轉(zhuǎn)并傳參就行。

注意點2:

問題:點擊購物車函數(shù)派發(fā)定義在詳情組件中,但是加入購物車接口調(diào)用在倉庫中,如何獲取調(diào)用函數(shù)的結(jié)果呢?

答案:第一種方案在vuex的state中保存結(jié)果,第二種方案在詳情組件中采用async+await修飾派發(fā)方法獲取調(diào)用成功失敗結(jié)果。

注意點3:

問題:如下代碼vuex中執(zhí)行ajax調(diào)用接口返回失敗,為啥?

src/api/index.js

//將產(chǎn)品添加到購物車中(獲取更新某一個產(chǎn)品的個數(shù))
// /api/cart/addToCart/{ skuId }/{ skuNum }  POST
export const addOrUpdateShopCar = (skuId, skuNum)=>requests({url:`/cart/addToCart/${skuId}/${skuNum}`, method:"post"});

src/store/detail/index.js

 async addOrUpdateShopCar(context, skuId, skuNum) {let response = await addOrUpdateShopCar(skuId, skuNum);console.log("******response:", response)       }

報錯如下:

在這里插入圖片描述

答案:vuex中action定義的函數(shù)接收形參書寫個數(shù)不對。

如果是一個參數(shù)可以寫成:addOrUpdateShopCar(context, skuId)
但如果是傳入多個參數(shù)則不能這樣寫:這是錯誤寫法:addOrUpdateShopCar(context, skuId, skuNum)
正確寫法是派發(fā)時傳入一個對象通過解構(gòu)方式獲取屬性值,正確寫法:addOrUpdateShopCar(context, {skuId, skuNum})

注意點4:

問題:理解異步函數(shù)async和await的用法?

答案:

  1. async 函數(shù)
    1)函數(shù)的返回值為Promise對象
    2)Promise對象的結(jié)果由async函數(shù)執(zhí)行的返回值決定
  2. await 表達式
    1)await右側(cè)的表達式一般為promise對象, 但也可以是其它的值
    2)如果表達式是promise對象,await就忙起來了,它會阻塞函數(shù)后面的代碼,等著Promise對象resolve,然后得到resolve的值,作為await表達式的運算結(jié)果。
    3)如果表達式是其它值, 直接將此值作為await的返回值
  3. asyncawait基于promise的。使用async的函數(shù)將會始終返回一個 promise 對象。這一點很重要,要記住,可能是你遇到容易犯錯的地方。
  4. 在使用await的時候我們只是暫停了函數(shù),而非整段代碼。
  5. async和await是非阻塞的
  6. 仍然可以使用 Promise,例如Promise.all().
  7. 注意
    1)await必須寫在async函數(shù)中, 但async函數(shù)中可以沒有await
    2)如果await的promise失敗了, 就會拋出異常, 需要通過try…catch來捕獲處理

29.2addCartSuce

重難點說明:區(qū)別使用sessionStorage與localStorage

addCartSuce

  • 查看詳情
  • 查看購物車

效果如圖

在這里插入圖片描述

修改代碼:

拷貝src/pages/AddCartSuccess文件夾

src/router/routes.js

import AddCartSuccess from '@/pages/AddCartSuccess'
import ShopCart from '@/pages/ShopCart'
{name: 'addCartSuccess',path: '/addCartSuccess',component: AddCartSuccess,meta:{"isShow": true}   //自定義元數(shù)據(jù)屬性,判斷Footer組件在底部是否顯示
},
{name: 'shopCart',path: '/shopCart',component: ShopCart,meta:{"isShow": true}   //自定義元數(shù)據(jù)屬性,判斷Footer組件在底部是否顯示
},

src/pages/AddCartSuccess/index.vue

<img :src="skuInfo.skuDefaultImg">
<p class="title">{{skuInfo.skuName}}</p>
<p class="attr">{{skuInfo.skuDesc}} 數(shù)量:{{$route.query.skuNum}}</p>
<router-link class="sui-btn btn-xlarge" :to="`/detail/${skuInfo.id}`">查看商品詳情</router-link>
<router-link to="/shopCart">去購物車結(jié)算</router-link>computed: {skuInfo() {return JSON.parse(sessionStorage.getItem("SKUINFO"))}
}

注意點1:

問題:點擊加入購物車按鈕后跳轉(zhuǎn)路由需要傳參購物詳情參數(shù),采用哪種方式?query?params?

答案:其實都可以,但是最優(yōu)雅的還是采用query方式,具體效果看如下:

  • 首先是采用params方式,地址欄顯示的是地址字符串,但組件中控制臺打印居然也能正確解析,說明能獲取到參數(shù),但是URL看起來一大長串東西還是不優(yōu)雅,萬一后續(xù)URL一頓追加參數(shù),豈不是越來越長根本不優(yōu)雅。

在這里插入圖片描述

  • 而采用query方式,地址欄很清爽,所以推薦采用這種方式傳參。

在這里插入圖片描述

注意點2:

問題:參數(shù)傳遞采用本地存儲好還是會話存儲好?

答案:推薦采用會話存儲,localStorage本地存儲會在硬盤保留一份需手動清除,而sessionStorage會話存儲隨著瀏覽器窗口關(guān)閉就清楚了,使用方便。

注意點3:

問題:無論是本地存儲還是會話存儲,可以存對象嗎?

答案:不能,只能存json字符串,直接存對象會無法解析。

  • 存儲存對象效果,這東西無法解析:

在這里插入圖片描述

29.3購物車

購物車

  • 購物車靜態(tài)組件-需要修改樣式結(jié)構(gòu)(刪除第三項并調(diào)整css讓各個項目對齊,比例為:15 35 10 17 10 13)
  • 向服務器發(fā)送ajax請求,獲取購物車數(shù)據(jù)
  • UUID臨時游客身份
  • 動態(tài)展示購物車

29.3.1 向服務器發(fā)送ajax請求,獲取購物車數(shù)據(jù)

修改代碼:

src/api/index.js

//獲取購物車列表數(shù)據(jù)接口
//URL:/api/cart/cartList   method:get
export const reqCartList = ()=>requests({url:'/cart/cartList ',method:'get'});

src/store/index.js

import shopCar from "@/store/shopCar"modules:{...shopCar}

src/store/shopCar/index.js

import {reqCartList} from "@/api";//shopCar模塊的小倉庫
//actions代表一系列動作,可以書寫自己的業(yè)務邏輯,也可以處理異步
const actions = {async reqCartList({commit}) {let response = await reqCartList();if (response.code == 200) {commit("REQ_CART_LIST", response.data)}},}
//mutations代表維護,操作維護的是state中的數(shù)據(jù),且state中數(shù)據(jù)只能在mutations中處理
const mutations = {REQ_CART_LIST(state, carList) {state.carList = carList},
}
//state代表倉庫中的數(shù)據(jù)
const state = {//購物車列表carList: [],
}
//計算屬性
//項目當中g(shù)etters主要的作用是:簡化倉庫中的數(shù)據(jù)(簡化數(shù)據(jù)而生)
//可以把我們將來在組件當中需要用的數(shù)據(jù)簡化一下【將來組件在獲取數(shù)據(jù)的時候就方便了】
const getters = {carList(state) {return state.carList[0] || {};}
}//創(chuàng)建并暴露store
export default {actions,mutations,state,getters
}

src/pages/ShopCart/index.vue

methods: {getData() {this.$store.dispatch('reqCartList')},},
mounted() {this.getData()
}

注意點1:如圖,這一列多余,刪除第三項并調(diào)整css讓各個項目對齊,比例為:15 35 10 17 10 13

在這里插入圖片描述

注意點2:

問題:向服務器發(fā)送查詢購物車ajax請求,獲取購物車數(shù)據(jù),為啥返回數(shù)據(jù)是空呢?

答案:因為你得帶UUID的東西,后端不知道你誰,也就不知道把那條數(shù)據(jù)返回給你了。

29.3.2UUID臨時游客身份

安裝命令:cnpm install --save uuid

修改代碼:

src/utils/uuid_token.js

import { v4 as uuidv4 } from 'uuid';
//要生成一個隨機字符串,且每次執(zhí)行不能發(fā)生變化,游客身份持久存儲
export const getUUID = ()=>{//先從本地存儲獲取uuid(看一下本地存儲里面是否有)let uuid_token = localStorage.getItem('UUIDTOKEN');//如果沒有if(!uuid_token){//我生成游客臨時身份uuid_token = uuidv4();//本地存儲存儲一次localStorage.setItem('UUIDTOKEN',uuid_token);}//切記有返回值,沒有返回值undefinedreturn uuid_token;
}

src/api/axios.js

//在當前模塊中引入store
import store from '@/store';
if(store.state.detail.uuid_token){//請求頭添加一個字段(userTempId):和后臺老師商量好了config.headers.userTempId = store.state.detail.uuid_token;
}

src/store/detail/index.js

const state = {//游客臨時身份uuid_token: getUUID()
}

注意點1:

問題:假設現(xiàn)在我有UUID了,那如何傳過去呢?接口已經(jīng)定義好了只有2個參數(shù),UUID咋傳過去?

答案:可以放在請求頭header中傳遞過去。

注意點2:

問題:我如何使用UUID第三方插件呢?

答案:登錄npm官網(wǎng)https://www.npmjs.com/package/uuid搜索uuid,下方就是使用方式。

在這里插入圖片描述

注意點3:切記UUID不能在vuex中生成,因為vuex是每次觸發(fā)就會隨機生成,會變動這是不行的,正常應該是一次生成有效期內(nèi)不改變。所以這個uuidv4()不能放在vuex中,最好放在src目錄下新建一個文件夾utils,這個文件夾里面經(jīng)常放一些常用的功能模塊,比如正則、臨時身份UUID等等。

注意點4:切記src/utils/uuid_token.js下封裝的uuid方法一定要有返回值,否則返回值是underfine無效的。

注意點5:

問題:在src/api/axios.js中現(xiàn)在需要給請求頭header添加uuid,但是uuid在vuex倉庫中,如何獲取呢?

答案:在src/api/axios.js中引入import store from ‘@/store’;,通過store 對象可以獲取倉庫中的state屬性。

29.3.3動態(tài)展示購物車

修改代碼:

src/pages/ShopCart/index.vue

<ul class="cart-list" v-for="(car, index) in cartInfoList" :key="car.id">
<input type="checkbox" name="chk_list" :checked="car.isChecked == 1">
<div class="item-msg">{{car.skuName}}</div>
<span class="price">{{car.skuPrice}}.00</span>
<input autocomplete="off" type="text" :value="car.skuNum" minnum="1" class="itxt">
<span class="sum">{{car.skuNum * car.skuPrice}}</span>
<i class="summoney">{{carTotalPrice}}</i>import {mapGetters} from "vuex";
data() {return {totalPrice: 0}},computed: {...mapGetters(["carList"]),//購物車數(shù)據(jù)cartInfoList() {return this.carList.cartInfoList || []},//計算購買產(chǎn)品的總價carTotalPrice() {this.cartInfoList.forEach(item => {this.totalPrice += item.skuNum * item.skuPrice;})return this.totalPrice;},//判斷底部復選框是否勾選【全部產(chǎn)品都選中,采勾選】isAllChecked() {//遍歷數(shù)組里面原理,只要全部元素isChecked屬性都為1===>真 true//只要有一個不是1======>假falsereturn this.cartInfoList.every(item=> item.isChecked == 1)}}

注意點1:

問題:查詢購物車信息的接口方法放在哪里?是放在“去購物車結(jié)算”按鈕還是放在“購物車”頁面加載完畢中定義?

答案:放在“購物車”頁面加載完畢中定義,只要購物車頁面一初始化,甭管哪個入口跳轉(zhuǎn)進來的都能進行批量查詢購物車數(shù)據(jù)并動態(tài)展示。

注意點2:購物車左下角的全選按鈕判斷是否勾選,推薦適用every而不是foreach方法

isAllChecked() {//遍歷數(shù)組里面原理,只要全部元素isChecked屬性都為1===>真 true//只要有一個不是1======>假falsereturn this.cartInfoList.every(item=> item.isChecked == 1)
}

29.4修改購物車產(chǎn)品的數(shù)量(需要發(fā)請求:參數(shù)理解)

修改代碼:

src/pages/ShopCart/index.vue

<li class="cart-list-con5"><a href="javascript:void(0)" class="mins" @click="handle('minus', -1, car)">-</a><input autocomplete="off" type="text" :value="car.skuNum" minnum="1" class="itxt" @change="handle('change', $event.target.value * 1, car)"><a href="javascript:void(0)" class="plus" @click="handle('add', 1, car)">+</a>
</li>//引入lodash:是把lodash全部封裝好的函數(shù)全都引入進來了
//按需引入:只是引入節(jié)流函數(shù),其他的函數(shù)沒有引入(模塊),這樣做的好處是,當你打包項目的時候體積會小一些
import throttle from "lodash/throttle";
methods: {//修改某一個產(chǎn)品的個數(shù)[節(jié)流]handle: throttle(async function(flag, disNum, car) {//type:為了區(qū)分這三個元素//disNum形參:+ 變化量(1)  -變化量(-1)   input最終的個數(shù)(并不是變化量)//cart:哪一個產(chǎn)品【身上有id】//向服務器發(fā)請求,修改數(shù)量switch (flag) {case "add"://加號disNum = 1;break;case "minus"://判斷產(chǎn)品的個數(shù)大于1,才可以傳遞給服務器-1//如果出現(xiàn)產(chǎn)品的個數(shù)小于等于1,傳遞給服務器個數(shù)0(原封不動)disNum = car.skuNum > 1 ? -1 : 0;break;case "change":/*用戶輸入進來的最終量,如果非法的(帶有漢字|出現(xiàn)負數(shù)),帶給服務器數(shù)字零* 問題:為啥是disNum < 1,而不是disNum <= 1* 答案:哪怕輸入1也會走else里面的代碼,不影響功能,所以無需加“=”等于號*/if (isNaN(disNum) || disNum < 1) {disNum = 0;} else {//屬于正常情況(小數(shù):取證),帶給服務器變化的量 用戶輸入進來的 - 產(chǎn)品的起始個數(shù)disNum = parseInt(disNum) - car.skuNum;}break;}try {//派發(fā)actionawait this.$store.dispatch('addOrUpdateShopCar', {skuId: car.skuId, skuNum: disNum})//再一次獲取服務器最新的數(shù)據(jù)進行展示this.getData();} catch (error) {//失敗alert(error.message);}}, 500),
}

注意點1:如圖,購物車中的【+、-、輸入值】都應該觸發(fā)修改購物車接口,且三個函數(shù)是同一個函數(shù)

在這里插入圖片描述

注意點2:

問題:如何區(qū)分是點擊了加號、減號、還是輸入值呢?

答案:通過傳參字符串flag標識名稱進行區(qū)分。

注意點3:

問題:實際觸發(fā)修改購物車接口的傳值要注意。

答案:點擊“+”號應傳值(1),點擊“-”號應傳值(-1),點擊輸入值應傳值(輸入值-原始值)。

注意點4:輸入框中事件一定要寫成@change,而不是@click,否則效果不對。

注意點5:

問題:對于“minus”情況,為啥是disNum < 1,而不是disNum <= 1

答案:哪怕輸入1也會走else里面的代碼,不影響功能,所以無需加“=”等于號

注意點6:點擊減號“-”要加判斷,不能讓值小于1。

case "minus"://判斷產(chǎn)品的個數(shù)大于1,才可以傳遞給服務器-1//如果出現(xiàn)產(chǎn)品的個數(shù)小于等于1,傳遞給服務器個數(shù)0(原封不動)disNum = car.skuNum > 1 ? -1 : 0;break;

注意點7:對于“change”情況,也要加判斷

case "change":/*用戶輸入進來的最終量,如果非法的(帶有漢字|出現(xiàn)負數(shù)),帶給服務器數(shù)字零* 問題:為啥是disNum < 1,而不是disNum <= 1* 答案:哪怕輸入1也會走else里面的代碼,不影響功能,所以無需加“=”等于號*/  if (isNaN(disNum) || disNum < 1) {disNum = 0;} else {//屬于正常情況(小數(shù):取證),帶給服務器變化的量 用戶輸入進來的 - 產(chǎn)品的起始個數(shù)disNum = parseInt(disNum) - car.skuNum;}break;

注意點8:

問題:連續(xù)點擊,居然能出現(xiàn)負數(shù),而慢慢點擊就不會出問題,為什么?

在這里插入圖片描述

答案:因為沒有加“節(jié)流”效果,由于點擊過快就會出現(xiàn)這種錯誤現(xiàn)象。

舊代碼:

//修改某一個產(chǎn)品的個數(shù)[節(jié)流]async handle(flag, disNum, car) {//type:為了區(qū)分這三個元素//disNum形參:+ 變化量(1)  -變化量(-1)   input最終的個數(shù)(并不是變化量)//cart:哪一個產(chǎn)品【身上有id】//向服務器發(fā)請求,修改數(shù)量switch (flag) {case "add"://加號disNum = 1;break;case "minus"://判斷產(chǎn)品的個數(shù)大于1,才可以傳遞給服務器-1//如果出現(xiàn)產(chǎn)品的個數(shù)小于等于1,傳遞給服務器個數(shù)0(原封不動)disNum = car.skuNum > 1 ? -1 : 0;break;case "change":/*用戶輸入進來的最終量,如果非法的(帶有漢字|出現(xiàn)負數(shù)),帶給服務器數(shù)字零* 問題:為啥是disNum < 1,而不是disNum <= 1* 答案:哪怕輸入1也會走else里面的代碼,不影響功能,所以無需加“=”等于號*/if (isNaN(disNum) || disNum < 1) {disNum = 0;} else {//屬于正常情況(小數(shù):取證),帶給服務器變化的量 用戶輸入進來的 - 產(chǎn)品的起始個數(shù)disNum = parseInt(disNum) - car.skuNum;}break;}try {//派發(fā)actionawait this.$store.dispatch('addOrUpdateShopCar', {skuId: car.skuId, skuNum: disNum})//再一次獲取服務器最新的數(shù)據(jù)進行展示this.getData();} catch (error) {//失敗alert(error.message);}},

修改后代碼

//引入lodash:是把lodash全部封裝好的函數(shù)全都引入進來了
//按需引入:只是引入節(jié)流函數(shù),其他的函數(shù)沒有引入(模塊),這樣做的好處是,當你打包項目的時候體積會小一些
import throttle from "lodash/throttle";//修改某一個產(chǎn)品的個數(shù)[節(jié)流]handle: throttle(async function(flag, disNum, car) {//type:為了區(qū)分這三個元素//disNum形參:+ 變化量(1)  -變化量(-1)   input最終的個數(shù)(并不是變化量)//cart:哪一個產(chǎn)品【身上有id】//向服務器發(fā)請求,修改數(shù)量switch (flag) {case "add"://加號disNum = 1;break;case "minus"://判斷產(chǎn)品的個數(shù)大于1,才可以傳遞給服務器-1//如果出現(xiàn)產(chǎn)品的個數(shù)小于等于1,傳遞給服務器個數(shù)0(原封不動)disNum = car.skuNum > 1 ? -1 : 0;break;case "change":/*用戶輸入進來的最終量,如果非法的(帶有漢字|出現(xiàn)負數(shù)),帶給服務器數(shù)字零* 問題:為啥是disNum < 1,而不是disNum <= 1* 答案:哪怕輸入1也會走else里面的代碼,不影響功能,所以無需加“=”等于號*/if (isNaN(disNum) || disNum < 1) {disNum = 0;} else {//屬于正常情況(小數(shù):取證),帶給服務器變化的量 用戶輸入進來的 - 產(chǎn)品的起始個數(shù)disNum = parseInt(disNum) - car.skuNum;}break;}try {//派發(fā)actionawait this.$store.dispatch('addOrUpdateShopCar', {skuId: car.skuId, skuNum: disNum})//再一次獲取服務器最新的數(shù)據(jù)進行展示this.getData();} catch (error) {//失敗alert(error.message);}}, 500),

29.5刪除某一產(chǎn)品

修改代碼:

app/src/api/index.js

//刪除購物產(chǎn)品的接口
//URL:/api/cart/deleteCart/{skuId}   method:DELETE
export const reqDeleteCartById = (skuId)=>requests({url:`/cart/deleteCart/${skuId}`,method:'delete'});

src/store/shopCar/index.js

import {reqDeleteCartById} from "@/api";const actions = {//刪除購物車某一個產(chǎn)品async reqDeleteCartById({commit}, skuId) {let response = await reqDeleteCartById(skuId);if (response.code == 200) {//返回的是成功的標記return "OK";} else {//返回的是失敗的標記return Promise.reject(new Error("fail"))}}
}

src/pages/ShopCart/index.vue

<a class="sindelet" @click="reqDeleteCartById(car.skuId)">刪除</a>//刪除某一個產(chǎn)品的操作
async reqDeleteCartById(skuId) {try {//派發(fā)actionawait this.$store.dispatch('reqDeleteCartById', skuId)this.getData();} catch (error) {alert(error.message)}
}

29.6修改產(chǎn)品狀態(tài)

修改代碼:

app/src/api/index.js

//修改商品的選中狀態(tài)
//URL:/api/cart/checkCart/{skuId}/{isChecked}   method:get
export const reqUpdateCheckedByid = (skuId,isChecked)=>requests({url:`/cart/checkCart/${skuId}/${isChecked}`,method:'get'});

src/store/shopCar/index.js

import {reqUpdateCheckedByid} from "@/api";const actions = {//修改購物車某一個產(chǎn)品的選中狀態(tài)async reqUpdateCheckedByid({commit}, {skuId,isChecked}) {let response = await reqUpdateCheckedByid(skuId,isChecked);if (response.code == 200) {//返回的是成功的標記return "OK";} else {//返回的是失敗的標記return Promise.reject(new Error("fail"))}},
}

src/pages/ShopCart/index.vue

<input type="checkbox" name="chk_list" :checked="car.isChecked == 1" @change="reqUpdateCheckedByid(car.skuId, $event)">//修改某個產(chǎn)品的勾選狀態(tài)async reqUpdateCheckedByid(skuId, event) {try {//如果修改數(shù)據(jù)成功,再次獲取服務器數(shù)據(jù)(購物車)let isChecked = event.target.checked ? "1" : "0";//派發(fā)actionawait this.$store.dispatch('reqUpdateCheckedByid', {skuId: skuId, isChecked})this.getData();} catch (error) {alert(error.message)}},

29.7刪除全部選中的商品

修改代碼:

src/pages/ShopCart/index.vue

<a @click="deleteAllCheckedCar">刪除選中的商品</a>//刪除全部選中的產(chǎn)品
//這個回調(diào)函數(shù)咱門沒辦法手機到一些有用數(shù)據(jù)
async deleteAllCheckedCar() {try {//成功//派發(fā)一個actionawait this.$store.dispatch('deleteAllCheckedCar')//再發(fā)請求獲取購物車列表this.getData()} catch (error) {//失敗alert(error.message)}
}

src/store/shopCar/index.js

//刪除全部勾選的產(chǎn)品
async deleteAllCheckedCar({dispatch, getters}) {//context:小倉庫,commit【提交mutations修改state】 getters【計算屬性】 dispatch【派發(fā)action】 state【當前倉庫數(shù)據(jù)】//獲取購物車中全部的產(chǎn)品(是一個數(shù)組)let primoseAll = [];getters.carList.cartInfoList.forEach(item => {let promise = item.isChecked == 1 ? dispatch('reqDeleteCartById', item.skuId) : '';//將每一次返回的Promise添加到數(shù)組當中primoseAll.push(promise);})//只要全部的p1|p2....都成功,返回結(jié)果即為成功//如果有一個失敗,返回即為失敗結(jié)果return Promise.all(primoseAll);}

注意點1:接口API未提供選中刪除的功能,只提供了單獨刪除的,所以可以采用批量循環(huán)刪除的方式。

注意點2:dispatch派發(fā)不僅可以存在于vue中使用,也可以在vuex倉庫中使用

注意點3:vuex倉庫中的context包含很多東西,包括【commit、dispatch、getters、state…】,具體如圖

在這里插入圖片描述

注意點4:Promise.all用法,all里面的是個數(shù)組,如果其中的子項promise有一個失敗,返回即為失敗結(jié)果。具體用法如下:

let primoseAll = [];
let promise = item.isChecked == 1 ? dispatch('reqDeleteCartById', item.skuId) : '';
//將每一次返回的Promise添加到數(shù)組當中
primoseAll.push(promise);
//只要全部的p1|p2....都成功,返回結(jié)果即為成功
//如果有一個失敗,返回即為失敗結(jié)果
return Promise.all(primoseAll);

29.8全選操作

修改代碼:

src/pages/ShopCart/index.vue

<input class="chooseAll" type="checkbox" :checked="isAllChecked && cartInfoList.length > 0" @click="updateAllCheckedCar($event.target.checked)">//修改全部產(chǎn)品的選中狀態(tài)
async updateAllCheckedCar(checked) {try {//成功//派發(fā)一個actionlet isChecked = checked ? "1" : "0";await this.$store.dispatch('updateAllCheckedCar', isChecked)//再發(fā)請求獲取購物車列表this.getData()} catch (error) {//失敗alert(error.message)}
},

src/store/shopCar/index.js

//修改全部產(chǎn)品的狀態(tài)
async updateAllCheckedCar({dispatch, getters}, isChecked) {//context:小倉庫,commit【提交mutations修改state】 getters【計算屬性】 dispatch【派發(fā)action】 state【當前倉庫數(shù)據(jù)】//獲取購物車中全部的產(chǎn)品(是一個數(shù)組)let primoseAll = [];getters.carList.cartInfoList.forEach(item => {let promise = dispatch('reqUpdateCheckedByid', {skuId:item.skuId, isChecked});//將每一次返回的Promise添加到數(shù)組當中primoseAll.push(promise);})//只要全部的p1|p2....都成功,返回結(jié)果即為成功//如果有一個失敗,返回即為失敗結(jié)果return Promise.all(primoseAll);}

注意點1:全選或全不選后的正確效果如圖

在這里插入圖片描述

注意點2:

問題:全部刪除后,左下角的勾選按鈕居然還是選中狀態(tài),需要優(yōu)化

答案:在后面多補充個cartInfoList.length > 0判斷條件即可

:checked="isAllChecked && cartInfoList.length > 0

本人其他相關(guān)文章鏈接

1.vue尚品匯商城項目-day04【24.點擊搜索按鈕跳轉(zhuǎn)后的頁面商品列表、平臺售賣屬性動態(tài)展示(開發(fā)Search組件)】
2.vue尚品匯商城項目-day04【25.面包屑處理關(guān)鍵字】
3.vue尚品匯商城項目-day04【26.排序操作(難點)】
4.vue尚品匯商城項目-day04【27.分頁器靜態(tài)組件(難點)】
5.vue尚品匯商城項目-day04【28.詳情頁面Detail】
6.vue尚品匯商城項目-day04【29.加入購物車操作(難點)】

http://m.risenshineclean.com/news/62568.html

相關(guān)文章:

  • 徐州哪有做網(wǎng)站的熱門seo推廣排名穩(wěn)定
  • 網(wǎng)站修改標題有影響嗎站長工具seo綜合查詢columbu cat
  • 網(wǎng)站制作長沙長沙企業(yè)網(wǎng)站設計
  • 流量網(wǎng)站應該怎么做seo分析seo診斷
  • wdcp網(wǎng)站遷移google play下載安卓
  • 廣州做網(wǎng)站哪家專業(yè)最近三天的新聞大事國內(nèi)
  • 建設一個看電影的網(wǎng)站營銷軟文范例大全100
  • 個人備案網(wǎng)站做網(wǎng)購網(wǎng)站購買友情鏈接網(wǎng)站
  • html5可以做交互網(wǎng)站嗎成都抖音seo
  • 個別網(wǎng)站網(wǎng)速慢怎么做電商網(wǎng)站設計方案
  • 變態(tài)魔域游戲廣州seo推廣營銷
  • 網(wǎng)站建設網(wǎng)站需要什么軟件有哪些營銷網(wǎng)站建設多少錢
  • 住房和城鄉(xiāng)建設部網(wǎng)站主頁免費關(guān)鍵詞挖掘工具
  • 代理平臺注冊網(wǎng)站建設腰椎間盤突出壓迫神經(jīng)腿疼怎么治
  • 企業(yè)門戶網(wǎng)站功能列表杭州seo 云優(yōu)化科技
  • b2c旅游網(wǎng)站管理系統(tǒng)seo短視頻入口引流
  • 網(wǎng)站建設服務器的選擇方式包括哪些免費網(wǎng)絡推廣平臺有哪些
  • 企業(yè)網(wǎng)站內(nèi)容更新怎么操作網(wǎng)站收錄查詢?nèi)肟?/a>
  • 重慶網(wǎng)站建設重慶網(wǎng)站設計免費入駐的賣貨平臺有哪些
  • 創(chuàng)新模式_提高質(zhì)量_建設一流的數(shù)學人才培養(yǎng)基地 教學成果獎申報網(wǎng)站詳細描述如何進行搜索引擎的優(yōu)化
  • 做網(wǎng)站只有域名哪個網(wǎng)站百度收錄快
  • 骨科醫(yī)院網(wǎng)站優(yōu)化服務商seo網(wǎng)絡推廣公司報價
  • 多語種網(wǎng)站營銷溫州seo服務
  • 做網(wǎng)站商城怎么樣國產(chǎn)長尾關(guān)鍵詞拘挖掘
  • 做網(wǎng)站銷售iis搭建網(wǎng)站
  • 找人做網(wǎng)站 優(yōu)幫云百度電話銷售
  • wordpress 微網(wǎng)站模板百度搜索平臺
  • wordpress網(wǎng)站插件軟文營銷的概念
  • 平面設計有什么網(wǎng)站360推廣
  • wordpress怎么改變文章的域名網(wǎng)站推廣的優(yōu)化