vuex購物車的實(shí)現(xiàn)具體流程

過程分析

1.首先購物車彈窗是一個組件,因?yàn)闀霈F(xiàn)在不同的頁面中。

2.因?yàn)楹芏嘟M件會用到購物車數(shù)據(jù)窄刘,所以統(tǒng)一放到vuex中。

實(shí)現(xiàn)步驟解析

一就谜、加入購物車

將購物車數(shù)據(jù)統(tǒng)一放在vuex中:

state里放置一個數(shù)組:carPanelData,里面放置購物車數(shù)據(jù)怪蔑。

// 購物車商品數(shù)據(jù)

state: {? ??

????carPanelData: []

}

往購物車?yán)飌ush數(shù)據(jù):在mutation里面更改state數(shù)據(jù)。

思路:首先需要將點(diǎn)擊加入購物車的每一條數(shù)據(jù)加一個屬性:count,計(jì)數(shù)丧荐,然后將這條點(diǎn)擊的商品數(shù)據(jù)push到state中缆瓣,當(dāng)然,首先是需要先用商品ID和state里的商品ID比對虹统,如果沒有就push弓坞,如果有了,就計(jì)數(shù)车荔。

以下是代碼思路

mutations:addCarPanelData(state,加入購物車的數(shù)據(jù)data){

//循環(huán)carPanelData購物車數(shù)據(jù)//如果商品ID存在(購物車的id和傳進(jìn)來的ID比對)渡冻,就設(shè)置count++

//設(shè)置開關(guān)false===================================================================? ?**注意** : 如果上面的條件成立,以下是不執(zhí)行的忧便,所以可以設(shè)置一個開關(guān)bOff

//如果開關(guān)值為true//否則就是商品ID不存在族吻,設(shè)置一個新的變量goodsData = 傳進(jìn)來的data;

//Vue.set(goodsData,'count',1):為這個變量設(shè)置count屬性珠增,值為1超歌;

//將這個goodsData,push到carPanelData中蒂教;? ? ? ? ? ? ??

}

mutations: {?

addCarPanelData (state,data) {

let bOff =truestate.carPanelData.forEach((goods) =>{

????????????????????????????????????????if(goods.sku_id === data.sku_id) {? ? ? ? ??

????????????????????????????????????????????????????goods.count++? ? ? ? ?

?????????????????????????????????????????????????????bOff =false

????????????????????????????????????????????}? ? ??

????????????????})

????????if(bOff) {

????????????let goodsData = data? ? ? ??

????????????Vue.set(goodsData,'count',1)? ? ? ??

????????????state.carPanelData.push(goodsData)? ? ??

????????}

????????console.log(state.carPanelData)? ??

????}??

}

在商品頁選擇了商品巍举,點(diǎn)擊加入購物車按鈕:這時,將這條數(shù)據(jù)傳給vuex悴品,記錄到state中(mutation里面已經(jīng)對該邏輯進(jìn)行了處理)

要點(diǎn): 記住vuex的思想禀综,要想改變state,必須提交mutation苔严。

methods:{? ? ??

? ?addCarPanelHandel(data){

????????????????//改變state定枷,必須提交mutation,并將此條數(shù)據(jù)傳給 vuex

????????????????this.$store.commit('addCarPanelData',data)? ? ? ?

?????????}

}

這時已經(jīng)基本完成了購物車的邏輯,下面届氢,我們把購物車單獨(dú)出來做成組件:car-panel欠窒。

這個時候就可以把相關(guān)數(shù)據(jù)綁定在購物車了。

要點(diǎn):如何獲取在購物車組件內(nèi)獲取vuex數(shù)據(jù)退子?

用computed即可岖妄。

//相應(yīng)的綁定代碼=示例{{item.title}})

//獲取vuex數(shù)據(jù)

computed : {? ? ? ??

????????????carPanelData(){

????????????????????return this.$store.state.carPanelData? ? ? ??

????????????},? ? ? ??

????????????count(){

????????????????????????return this.$store.getters.totleCount? ? ? ??

????????????},? ? ? ??

????????????totle(){

????????????????????return? ?this.$store.getters.totlePrice? ? ? ??????

????????????}

}

最后,對購物車中的商品數(shù)量和商品總價計(jì)算寂祥。

在vue中荐虐,我們需要對變量進(jìn)行進(jìn)一步處理,可以放在computed里丸凭,不建議放在模板中福扬,同樣腕铸,vuex中,state中的狀態(tài)如果需要進(jìn)一步處理铛碑,我們可以放入getters.

getters:{

????// 購物車商品數(shù)量計(jì)算

totleCount (state) {

????????let count =0state.carPanelData.forEach((goods) =>{? ? ? ??

????????????????????count += goods.count? ? ??

????????})

????????return? count? ??

},

// 總價格

totlePrice (state) {

????????????let price =0state.carPanelData.forEach((goods) =>{? ? ? ??

????????????????????price += goods.price * goods.count? ? ?

????????????})

? ? ? ? ? ? ? return price? ??

????????}??

}

============================================================

至此狠裹,已經(jīng)完成了加購物車,并且計(jì)算數(shù)量和金額汽烦。

============================================================

二涛菠、購物車刪除

一開始我的思路是

1、刪除數(shù)據(jù)肯定是要改變state撇吞,改變state肯定是需要提交mutation,所以刪除的相關(guān)邏輯方法應(yīng)該寫在mutation俗冻;

2、當(dāng)時我的問題是如何知曉刪除的是哪一條數(shù)據(jù)梢夯?

通過學(xué)習(xí)言疗,弄清楚了,以后此類需求颂砸,都和加入購物和思路是一致的,都是通過對比刪除的當(dāng)前的ID和數(shù)據(jù)里的所有ID進(jìn)行比對死姚,就知道是刪除具體哪條數(shù)據(jù)了人乓。

3、那么我需要記住都毒,當(dāng)前選擇的是哪條數(shù)據(jù)色罚,都是通過在刪除的點(diǎn)擊方法對應(yīng)的事件里,參數(shù)中傳遞當(dāng)前數(shù)據(jù)(商品ID)即可账劲。這是一個思路戳护,需要牢記

具體實(shí)現(xiàn)步驟總結(jié)

點(diǎn)擊購物車頁面的刪除商品按鈕瀑焦,綁定一個刪除方法腌且,參數(shù)傳入當(dāng)前被點(diǎn)擊的商品ID,在這個方法里調(diào)用mutation里面的刪除商品方法:

首先需要循環(huán)state的購物車數(shù)據(jù)榛瓮;

比對每一項(xiàng)的商品ID是否和當(dāng)前傳入的ID相同铺董,如果是相同的那么就return,不再繼續(xù)循環(huán)了禀晓;

在state的購物車數(shù)據(jù)里刪除這項(xiàng)ID相同的數(shù)據(jù)精续。

//mutation?

? delCarPanelData (state,id) {??

????????? ? state.carPanelData.forEach((goods,index) => {

????????????????????????if(goods.sku_id === id) {

????????????????????? ? ? ? ? state.carPanelData.splice(index,1)

????????????????????????????????return

????????????????????????????}? ? ??

????????????})

}

//購物車組件中

????methods: {? ? ? ??

????????????????delCarPanelHandel(id){

????????????????? ? ? ? ? ? this.$store.commit('delCarPanelData',id)? ? ? ??

????????????????}

}

刪除

三、購物車商品數(shù)量限制

思路: 這類顯示隱藏的案例粹懒,都是設(shè)置變量屬性的ture/false

首先是有一個彈窗組件重付,當(dāng)商品數(shù)量大于最大值得時候,這個組件需要彈出凫乖。

數(shù)據(jù)中已經(jīng)有了最大值 : limit_num确垫。

在state中定義一個變量:maxOff :false ,默認(rèn)不顯示愕把,當(dāng)購物車中商品增加的時候,比對當(dāng)前商品的數(shù)量是否已經(jīng)大于了limit_num森爽,如果是恨豁,就讓這個彈窗出來,也就是在mutation中設(shè)置該屬性為true爬迟。

商品數(shù)量超過后顯示彈窗

// 加入購物車

addCarPanelData (state,data) {? ? ?

?????????????state.carPanelData.forEach((goods) =>{

????????????????????????if(goods.sku_id === data.sku_id) {??

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?goods.count++? ? ? ? ??

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?bOff =false? //比較當(dāng)前商品的數(shù)量和數(shù)據(jù)中的商品最大購買數(shù)量? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if(goods.count > goods.limit_num) {? ? ? ? ? ?

?????????????????????????????????????????????????goods.count--? ? ? ? ? ??

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? state.maxOff =true

????????????????????????????????????}? ? ? ?

?????????????????????????}? ? ??

????????????????})?

}

//組件中

computed: {? ? ? ??

????????????maxOff(){

????????????????return this.$store.state.maxOff? ? ? ??

????????????}??

}

關(guān)閉彈窗

//mutations

????????closePrompt (state) {? ??

?????????????????state.maxOff =false

????????}

//組件中

methods : {? ? ?

?????closePrompt(){

? ? ? ?this.$store.commit('closePrompt')? ? ??

?????}??

?}

四橘蜜、購物車顯示隱藏

思路: 一樣的,這類顯示隱藏付呕,需要設(shè)置一個開關(guān)计福,去切換開關(guān)即可。

state: {

? ? ? ? ?carPanelData: [],

? ? ? ? ? maxOff:false,// 彈窗開關(guān)

? ? ? ? ?carShow :false,// 購物車開關(guān)

? ? ? ? ? carTimer :null// 購物車定時器

? ?},

// 購物車顯示

? showCar (state) {? ? ??

? ? ?clearTimeout(state.carTimer)? ? ??

? ? ?state.carShow =true

?},

// 購物車隱藏

hideCar (state) {? ? ??

? ? ?state.carTimer = setTimeout(()=>{?

????????????????state.carShow =false

????????????},1000)? ? }

//組件中

methods: {

????// 顯示購物車

????showCar(){

????????????this.$store.commit('showCar')? ? ? ?

?????},

????// 隱藏購物車

????hideCar(){

????????????this.$store.commit('hideCar')? ? ? ??

????}

?}

四徽职、購物車小球效果

思路:用的vue的transtion鉤子函數(shù)象颖,原理就是先把小球?qū)懰赖劫徫镘嚕c(diǎn)擊的時候瞬間移入到需要的位置姆钉,然后做一個過渡動畫即可说订,加入貝塞爾曲線。

state: {

? ? ? ? ? ? ? ? ball: { // 購物車小球

????????????????????????????????show:false,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? el:null,// 點(diǎn)擊的是哪個購物車按鈕

????????????????????????????????????img:''

? ? ? ? ? ? ? }

}

mutations: {

?// 加入購物車

? addCarPanelData (state,data) {

? ? ? ? ? // 加上這個條件潮瓶,確保小球飛完再添加

? ? ? ? ? ?if(!state.ball.show){?

????????????????????// 顯示購物車

? ? ? ? ? ? ? ? ? ? ? state.carShow =true

? ? ? ? ? ? ? ? ? ? ?let bOff =true?

? ? ? ? ? ? ? ? ? ? ? state.carPanelData.forEach((goods) =>{

????????????????????????????// 比對ID陶冷,相同就說明購物車已存在此商品,數(shù)量增加

????????????????????????????if(goods.sku_id===data.sku_id) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? goods.count++

????????????????????????????????????bOff = false?

????????????????????????????????????if(goods.count > goods.limit_num) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?????????goods.count--

????????????????????????????????????????????state.maxOff = true

????????????????????????????????????????????????????return

? ? ? ? ? ? ? ? ? ? ? ? }?

????????????????????????//加入購物車毯辅, 小球顯示

????????????????????????state.ball.show = true

? ? ? ? ? ? ? ? ? ? ? ? ?state.ball.img = data.ali_image?

? ? ? ? ? ? ? ? ? ? ? ? ? ?// 通過event對象獲取到當(dāng)前點(diǎn)擊的按鈕

????????????????????????????state.ball.el = event.path[0]?

????????????}?

????????})

????????????//商品不存在埂伦, 就往數(shù)組里新增商品數(shù)據(jù)

? ? ? ? ? if(bOff) {

? ? ? ? ? ? ? ? ? ? ? let goodsData = data Vue.set(goodsData, 'count', 1) ????????????????????????state.carPanelData.push(goodsData) // 加入購物車,小球顯示

????????????????????????state.ball.show= true?

????????????????????????state.ball.img = data.ali_image?

????????????????????????// 通過event對象獲取到當(dāng)前點(diǎn)擊的按鈕

????????????????????????state.ball.el = event.path[0]?

????????????????}

????????????console.log(event)?

????}?

}

//組件內(nèi)//

?小球進(jìn)入前, 初始化

beforeEnter(el) {?

????// 獲取按鈕的位置

????let rect =this.ball.el.getBoundingClientRect()

????// 獲取購物車

? ? ?let rectEl =document.getElementsByClassName('ball-rect')[0].getBoundingClientRect()

? ?//獲取小球

????let ball = document.getElementsByClassName('mask-item')[0]?

????//計(jì)算按鈕和購物車的差值 : 購物車的中心點(diǎn)到左側(cè)的距離 - 按鈕中心點(diǎn)到左側(cè)的距離

? ? ? ?let x = (rectEl.left+16) - (rect.left + rect.width / 2)?

? ? ? ?let y = rect.top + rect.height / 2 -rectEl.top + 5 - 16?

????????//計(jì)算小球和包著小球的父級的位置

????????ball.style.transform ='translate3d(-'+x+'px,0,0)'

? ? ? ? el.style.transform= 'translate3d(0,' + y + 'px,0)'

? ? ? ? ?ball.src = this.ball.imgconsole.log(this.ball.img)

},?

//開始運(yùn)動

enter (el){

????????let a = el.offsetHeight

????????// 獲取小球

????????let ball = document.getElementsByClassName('mask-item')[0]?

????????el.a = a?

? ? ? ? ?//避免變量沒有使用思恐,eslint報(bào)錯

????????el.style.transform ="translate3d(0,0,0)"

????????ball.style.transform= "translate3d(0,0,0)"

},?

// 結(jié)束沾谜,讓小球隱藏

????afterEnter (el){

????????????this.ball.show =false

????}


.ball-enter-active{?

????????????transition:1 s cubic - bezier(.18, 1, .94, 1)

? ? }

.ball - enter - active.mask - item {

? ? ? ? ? ? ? ? ? ? transition: 1 s cubic - bezier(0, 0, 0, 0)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市胀莹,隨后出現(xiàn)的幾起案子基跑,更是在濱河造成了極大的恐慌,老刑警劉巖嗜逻,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涩僻,死亡現(xiàn)場離奇詭異,居然都是意外死亡栈顷,警方通過查閱死者的電腦和手機(jī)逆日,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萄凤,“玉大人室抽,你說我怎么就攤上這事∶遗” “怎么了坪圾?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵晓折,是天一觀的道長。 經(jīng)常有香客問我兽泄,道長漓概,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任病梢,我火速辦了婚禮胃珍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜓陌。我一直安慰自己觅彰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布钮热。 她就那樣靜靜地躺著填抬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪隧期。 梳的紋絲不亂的頭發(fā)上飒责,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機(jī)與錄音厌秒,去河邊找鬼读拆。 笑死,一個胖子當(dāng)著我的面吹牛鸵闪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播暑诸,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蚌讼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了个榕?” 一聲冷哼從身側(cè)響起篡石,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎西采,沒想到半個月后凰萨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡械馆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年胖眷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霹崎。...
    茶點(diǎn)故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡珊搀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出尾菇,到底是詐尸還是另有隱情境析,我是刑警寧澤囚枪,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站劳淆,受9級特大地震影響链沼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沛鸵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一括勺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谒臼,春花似錦朝刊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至底哥,卻和暖如春咙鞍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背趾徽。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工续滋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人孵奶。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓疲酌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親了袁。 傳聞我的和親對象是個殘疾皇子朗恳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容