1.定义全局数据共享store
import Vue from 'vue'
import Vuex from 'vuex'
import moduleCart from '@/store/cart.js'
Vue.use(Vuex)
const store=new Vuex.Store({
modules:{
'm_cart':moduleCart
}
})
export default store
2.把store挂载到vue
import App from './App'
import Vue from 'vue'
import './uni.promisify.adaptor'
import store from '@/store/store.js'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App,
store
})
...
3.store —cart.js
export default {
namespaced: true,
state: () => ({
cart: JSON.parse(uni.getStorageSync('cart') || '[]')
}),
mutations: {
addToCart(state, goods) {
const findRes = state.cart.find(x => x.id === goods.id);
if (!findRes) {
state.cart.push(goods);
} else {
findRes.count++;
}
this.commit('m_cart/saveToStorage')
},
saveToStorage(state) {
uni.setStorageSync('cart', JSON.stringify(state.cart))
}
},
getters: {
total(state) {
let c = 0;
state.cart.forEach(goods => c += goods.count)
return c
}
}
}
4.详情页面代码
<template>
<view class="goods-detail-container">
<!-- 轮播图 -->
<swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000" :circular="true">
<swiper-item v-for="(item,i) in goodsInfo.picsList" :key="i">
<image :src="item" @click="preview(i)"></image>
</swiper-item>
</swiper>
<!-- 商品信息 -->
<view class="goods-info-box">
<!-- 商品价格 -->
<view class="goods-price">¥{{goodsInfo.price}}</view>
<view class="goods-info-body">
<!-- 商品名称 -->
<view class="goods-name">{{goodsInfo.name}}</view>
<!-- 收藏 -->
<view class="favi">
<uni-icons type="star" size="18" color="gray"></uni-icons>
<text>收藏</text>
</view>
</view>
<view class="yf">快递:免运费</view>
</view>
<!-- 详情 -->
<!-- <rich-text :nodes="goodsInfo.introduce"></rich-text> -->
<view v-for="(item) in 20">xxxxxxxxxxxxxxxxxxxxxxxxxxxx{{item}}</view>
<!-- 底部商品导航组件 -->
<view class="goods-nav">
<uni-goods-nav :fill="true" :options="options" :buttonGroup="buttonGroup" @click="onClick"
@buttonClick="buttonClick" />
</view>
</view>
</template>
<script>
import {
mapState,
mapMutations,
mapGetters
} from 'vuex';
export default {
computed: {
...mapState('m_cart', ['cart']),
...mapGetters('m_cart', ['total'])
},
watch: {
total: {
handler(newVal) {
const findRes = this.options.find(x => x.text === '购物车');
if (findRes) {
findRes.info = newVal;
}
},
immediate: true
}
},
data() {
return {
goodsInfo: {},
options: [{
icon: 'headphones',
text: '客服'
}, {
icon: 'shop',
text: '店铺',
info: 0,
infoBackgroundColor: '#007aff',
infoColor: "white"
}, {
icon: 'cart',
text: '购物车',
info: 0
}],
buttonGroup: [{
text: '加入购物车',
backgroundColor: 'linear-gradient(90deg, #1E83FF, #0053B8)',
color: '#fff'
},
{
text: '立即购买',
backgroundColor: 'linear-gradient(90deg, #60F3FF, #088FEB)',
color: '#fff'
}
]
}
},
onLoad(options) {
const id = options.id;
this.getGoodsDetail(id);
},
methods: {
...mapMutations('m_cart', ['addToCart']),
getGoodsDetail(id) {
uni.request({
url: uni.$baseUrl + '/api/Home/GetGoodsDetail',
data: {
"id": 1019
}
}).then((res) => {
if (res.data.code != 200) return uni.$showMsg();
this.goodsInfo = res.data.data;
});
},
preview(i) {
uni.previewImage({
current: i,
urls: this.goodsInfo.picsList.map(x => x)
})
},
onClick(e) {
if (e.content.text === '购物车') {
uni.switchTab({
url: '/pages/cart/cart'
})
}
},
buttonClick(e) {
if (e.content.text === '加入购物车') {
const goods = {
id: this.goodsInfo.id,
name: this.goodsInfo.name,
price: this.goodsInfo.price,
count: 1,
logo: this.goodsInfo.logo,
state: true
}
this.addToCart(goods);
}
}
}
}
</script>
<style lang="scss">
swiper {
height: 750rpx;
image {
width: 100%;
height: 100%;
}
}
.goods-info-box {
padding: 10px;
padding-right: 0;
.goods-price {
color: #c00000;
font-size: 18px;
margin: 10px 0;
}
.goods-info-body {
display: flex;
justify-content: space-between;
.goods-name {
font-size: 13px;
margin-right: 10px;
}
.favi {
width: 120px;
font-size: 12px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-left: 1px solid #efefef;
color: gray;
}
}
.yf {
font-size: 12px;
color: gary;
margin: 10px 0;
}
}
.goods-nav {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
}
.goods-detail-container {
padding-bottom: 50px;
}
</style>
5.效果示例