问题遇到的现象和发生背景
uniapp做的购物车功能,getters里定义了总价,但是在改变价格类型时总价没变,realPrice改变没有触发getters里allInfo的执行。
问题相关代码,请勿粘贴截图
<template>
<view>
<!-- 空购物车 -->
<van-empty description="您的进货单还空着呢,去逛逛吧" v-if="!cartList.length">
<van-button round type="primary" class="bottom-button" @click="goIndex">去逛逛</van-button>
</van-empty>
<!-- 购物车列表 -->
<view v-for="(item,index) in cartList" :key="item.id" class="bg-white solid-bottom cu-list">
<view class="flex padding align-center cu-item" @touchstart="ListTouchStart"
:class="modalName=='move-box-'+ index?'move-cur':''" @touchmove="ListTouchMove" @touchend="ListTouchEnd"
:data-target="'move-box-' + index">
<view class="flex align-center">
<view class="iconfont icon-gouxuan" :class="item.ischeck?'color-0e932e':''"
@click="handleCheck(index)">
</view>
</view>
<view class="flex justify-between padding-left-sm">
<view class="margin-xs">
<view class="action text-df">
<text class="cuIcon-shop text-blue"></text>
<text class="text-black">{{item.product.supplier.name}}</text>
</view>
{{item.product.name}}
<view class="margin-tb-xs">产品编号:{{item.product.id}}</view>
<text class="text-red">¥{{item.realPrice}}</text>
</view>
<view class="action">
<u-number-box :min="1" v-model="item.num" integer button-size="22"
@change="handleNum($event,index)">
</u-number-box>
</view>
</view>
<view class="move" @click="handleDelete(item.id, index)">
<view class="bg-red">删除</view>
</view>
</view>
</view>
<!-- 不同价格类型 -->
<view class="priceType cu-bar bg-white tabbar border shop">
<radio-group @change="handleRadio" class="flex padding justify-center">
<label v-for="(item, index) in radioGroup" class="padding-left-sm" :key="item.key">
<radio class='radio' :value="item.key" :checked="item.key==activeRadio" />{{item.value}}
</label>
</radio-group>
</view>
<!-- 底部操作栏 -->
<view class="cu-bar foot bg-white tabbar border shop">
<view class="flex padding" @click="handleAllCheck(allInfo.allCheck)" data-target="bottomModal">
<view class="iconfont icon-gouxuan" :class="allInfo.allCheck?'color-0e932e':''">
</view>
<text class="padding-left-sm">全选</text>
</view>
<view class="flex-twice text-red">
共计: {{allInfo.allPrice}}元
</view>
<view @click="handleOrder" class="flex-treble bg-main submit">立即下单</view>
</view>
</view>
</template>
<script>
import {
mapState,
mapActions,
mapMutations,
mapGetters
} from 'vuex'
import {
$post
} from '@/utils/request.js';
import {
purchaserShoppingManage,
purchaserShoppingCart
} from '@/utils/config.js';
export default {
onShow(option) {
// this.$store.dispatch('cart/cartListInitAct')
this.cartListOnLoad();
},
data() {
return {
modalName: null,
listTouchStart: 0,
listTouchDirection: null,
cartInfo: {
id: '',
num: 0
},
activeRadio: 'MARKET_PRICE',
radioGroup: [{
key: 'MARKET_PRICE',
value: '市场价'
}, {
key: 'PRICE_AFTER_TAX',
value: '含税协议价'
}, {
key: 'PRICE_BEFORE_TAX',
value: '非含税协议价'
}]
};
},
computed: {
...mapState({
cartList: state => state.cart.cartList,
priceType: state => state.cart.priceType,
// userInfo:state=>state.user.userInfo
}),
...mapGetters({
allInfo: 'cart/allInfo'
})
},
methods: {
...mapMutations({
handleRadioMut: 'cart/handleRadioMut',
handleCheck: 'cart/cartCheckMut',
handleAllCheck: 'cart/cartAllCheckMut',
cartListInitMut: 'cart/cartListInitMut'
}),
cartListOnLoad() {
console.log("cartListOnLoad==", this.$store)
$post('/auth-api/shop-cart/get-list').then(res => {
console.log("cartListOnLoad== ", res);
// this.$store.state.cartList = res.body
this.cartListInitMut(res.body)
})
},
//改变价格种类---------------------------------这个方法没有触发getters
handleRadio(e) {
this.activeRadio = e.detail.value
this.$store.state.priceType = this.activeRadio
this.handleRadioMut(this.activeRadio)
},
showModal(e) {
this.modalName = e.currentTarget.dataset.target
},
hideModal(e) {
this.modalName = null
},
// ListTouch计算滚动
ListTouchEnd(e) {
if (this.listTouchDirection == 'left') {
this.modalName = e.currentTarget.dataset.target
} else {
this.modalName = null
}
this.listTouchDirection = null
},
// ListTouch触摸开始
ListTouchStart(e) {
this.listTouchStart = e.touches[0].pageX
},
// ListTouch计算方向
ListTouchMove(e) {
this.listTouchDirection = e.touches[0].pageX - this.listTouchStart > 0 ? 'right' : 'left'
},
// 去逛逛
goIndex() {
uni.switchTab({
url: '../product/product'
})
},
//数量加减
handleNum(e, index) {
console.log("this.cartInfo this.$store.state", this.$store.state)
this.num = e.value
this.cartInfo.id = this.$store.state.cart.cartList[index].id
this.cartInfo.num = e.value
console.log("this.cartInfo", this.cartInfo)
$post('/auth-api/shop-cart/update', this.cartInfo, purchaserShoppingCart).then(res => {
console.log("update== ", res);
})
},
handleOrder() {
let nullCart = true;
let products = [];
let supplierId = [];
this.cartList.forEach(item => {
if (item.ischeck) {
nullCart = false
products.push(item)
if (supplierId.indexOf(item.product.supplier.id) == -1) {
supplierId.push(item.product.supplier.id);
}
}
})
//购物车都没被选中
if (nullCart) {
uni.showModal({
content: '请选择商品'
})
return
}
//判断是否选择价格类型
if (this.activeRadio == '') {
uni.showModal({
content: '请选择价格类型'
})
return
}
//判断所选商品均为同一供应商
console.log(supplierId.length)
if (supplierId.length > 1) {
uni.showModal({
content: '请选择同一供应商的商品'
})
return
}
console.log("products==", products)
uni.navigateTo({
url: '../order/order?products=' +
encodeURIComponent(JSON.stringify(products)) +
'&allPrice=' + encodeURIComponent(JSON.stringify(this.allInfo.allPrice)) +
'&supplierId=' + encodeURIComponent(JSON.stringify(supplierId[0])) +
'&realPriceType=' + encodeURIComponent(JSON.stringify(this.activeRadio))
})
},
handleDelete(id, index) {
//调用删除接口
this.cartInfo.id = id
$post('/auth-api/shop-cart/delete', this.cartInfo, purchaserShoppingCart).then(res => {
console.log("create== ", res);
})
//删除成功
this.cartList.splice(index, 1)
uni.showToast({
title: '删除成功',
icon: 'none', //如果要纯文本,不要icon,将值设为'none'
duration: 1500 //持续时间为 2秒
})
console.log("=this.cartList=", this.cartList)
},
}
}
</script>
<style lang="scss">
page {
padding-bottom: 200upx;
}
.priceType {
position: fixed;
width: 100%;
bottom: 100upx;
z-index: 1024;
box-shadow: 0 -1upx 6upx rgba(0, 0, 0, 0.1);
}
.van-card__thumb image {
width: 100%;
height: 100%;
}
.icon-gouxuan {
color: #e7e7e7;
}
.flex.align-end {
min-width: 210upx;
}
</style>
JS代码如下:
import {
$post,
$get
} from '../utils/request.js'
import Vue from 'vue'
export default {
namespaced: true,
state() {
return {
cartList: [],
priceType: 'MARKET_PRICE'
}
},
getters: {
allInfo(state) { //统计信息
let allCheck = true
let allPrice = 0 //总价
let { cartList, priceType } = state
console.log("调用allInfo cartList== ", cartList, priceType);
cartList.forEach(item => {
if (!item.ischeck) {
allCheck = false
}
if (item.ischeck) {
allPrice += item.realPrice * item.num
}
})
return {
allCheck,
allPrice
}
}
},
mutations: {
cartListInitMut(state, res) { //初始化进货单列表
state.cartList = res
state.cartList.forEach(item => {
item.realPrice = item.product.marketPrice
item.realPriceType = state.priceType
})
console.log("cartListInitMut== ", state.cartList);
},
cartCheckMut(state, idx) { //单选
state.cartList[idx].ischeck = !state.cartList[idx].ischeck
},
//选择价格类型
handleRadioMut(state, activeRadio) {
state.cartList.forEach(item => {
item.realPriceType = activeRadio
if (item.product.quotedPrice && item.product.quotedPrice.enable) {
item.realPrice = activeRadio == 'MARKET_PRICE' ? item.product.marketPrice :
(activeRadio == 'PRICE_AFTER_TAX' ?
item.product.quotedPrice.priceAfterTax :
item.product.quotedPrice.priceBeforeTax)
} else {
item.realPrice = item.product.marketPrice
}
})
},
cartAllCheckMut(state, bool) { //全选,bool为原本的全选状态
state.cartList.forEach(item => {
item.ischeck = !bool
})
},
},
actions: {
}
}
运行结果及报错内容
我的解答思路和尝试过的方法
图中的1、2、3都可以触发总价allPrice改变,4这里的价格类型改变没法触发,刚接触vue,希望大家帮忙看看是什么原因,感谢!