踩坑日记 《正确的使用Vuex》基于 uniapp Vue3 setup 语法糖 vuex4 项目 太多坑了要吐了

完美解决页面数据不刷新 或者数据慢一步刷新

  • 页面使用
  • html
<template>
	<view>
		<template v-if="cartData.data.length>0">
			<!-- 自定义导航栏 -->
			<view class="box-bg" style="font-size: 36rpx;">
				<!-- <uni-nav-bar shadow left-icon="left" right-icon="cart" title="购物车" /> -->
				<uni-nav-bar shadow fixed="true" left-icon="left" :right-text="isEdit?'完成':'编辑'" title="购物车"
					statusBar="true" @clickRight="isEdit=!isEdit" />
			</view>
			<!-- 商品内容 -->
			<view class="shop-info">
				<view class="shop-item" v-for="(items, index) in cartData.data" :key="index">
					<label class="radio">
						<radio value="" color="#F33" @tap="selectedItemOne(index)" :checked="items.checked" />
						<text></text>
					</label>
					<image class="shop-image" :src="items.imgUrl" mode=""></image>
					<!-- 文字 -->
					<view class="shop-text">
						<view class="shop-name">{{items.name}}</view>
						<view class="shop-color f-color">颜色:{{items.color}}</view>
						<view class="shop-price-num">
							<view class="shop-price">¥{{items.nprice}}</view>
							<view class="shop-num">x {{items.num}}</view>
						</view>
					</view>
				</view>
			</view>

			<!-- 底部内容 -->
			<view class="shop-foot">
				<label class="foot-radio">
					{{checkedall.data}}
					<radio value="" color="#F33" @tap="checkAllFunc" :checked="checkedall.data" /><text>全选</text>
				</label>

				<view class="foot-text">
					<view class="foot-center">
						<view class="foot-count">合计:¥<span class="f-active-color">0</span>
							<view class="foot-tips">不包含运费</view>
						</view>
					</view>
					<view class="foot-num">结算(0)</view>
				</view>
			</view>
		</template>

		<template v-else>
			<!-- 自定义导航栏 -->
			<view class="box-bg" style="font-size: 36rpx;">
				<!-- <uni-nav-bar shadow left-icon="left" right-icon="cart" title="购物车" /> -->
				<uni-nav-bar statusBar="true" fixed="true" title="购物车" />
			</view>
			<view>
				<image class="shop-info-else" src="../../static/cartImage/isNull.png"></image>
			</view>
		</template>
	</view>
</template>
  • javascript
<script setup>
	import {
		ref,
		reactive,
		computed,
	} from "vue"

	import {
		useStore
	} from 'vuex'
	import store from '@/store/index.js'
	// 购物车商品数据
	const cartData = reactive({
		data: computed(() => {
			return store.state.cart.cartData
		})
	})
	console.log(cartData.data);

	// 全选
	const checkAllFunc = () => {
		store.dispatch("checkAllFunc")
	}

	// 获取全选状态
	const checkedall = reactive({
		data: computed(() => {
			return store.getters["checkedAll"]
		})
	})
	// 全选
	const selectedItemOne = (index) => {
		store.commit("oneCheck", index)
	}
	// 编辑 or 确定
	const isEdit = ref(false)
</script>
  • store
    • index.js
import { createStore } from 'vuex'
import cart from "@/store/modules/cart.js"
export default createStore({
	modules: {
		cart,
	}
})
  • store
    • modules
      • cart.js
const getDefaultState = () => {
	return {
		// token: getToken(),
		cartData: [{
				checked: false,
				id: 1,
				name: "正版护奶裙日系jk制服套装显瘦学院风甜美背带连衣裙夏季中长裙子甜美背带连衣裙夏季中长裙",
				color: "哈哈短会十大",
				imgUrl: "../../static/shopImage/shopInfo/jk02.png",
				nprice: "999",
				num: 1,
			},
			{
				checked: false,
				id: 2,
				name: "正版护奶裙日系jk制服套装显瘦学院风甜美背带连衣裙夏季中长裙子甜美背带连衣裙夏季中长裙",
				color: "哈哈短会十大",
				imgUrl: "../../static/shopImage/shopInfo/jk02.png",
				nprice: "99",
				num: 2,
			},
			{
				checked: false,
				id: 3,
				name: "正版护奶裙日系jk制服套装显瘦学院风甜美背带连衣裙夏季中长裙子甜美背带连衣裙夏季中长裙",
				color: "哈哈短会十大",
				imgUrl: "../../static/shopImage/shopInfo/jk02.png",
				nprice: "990",
				num: 1,
			},
			{
				checked: false,
				id: 4,
				name: "正版护奶裙日系jk制服套装显瘦学院风甜美背带连衣裙夏季中长裙子甜美背带连衣裙夏季中长裙",
				color: "哈哈短会十大",
				imgUrl: "../../static/shopImage/shopInfo/jk02.png",
				nprice: "990",
				num: 1,
			},
			{
				checked: false,
				id: 5,
				name: "正版护奶裙日系jk制服套装显瘦学院风甜美背带连衣裙夏季中长裙子甜美背带连衣裙夏季中长裙",
				color: "哈哈短会十大",
				imgUrl: "../../static/shopImage/shopInfo/jk02.png",
				nprice: "990",
				num: 1,
			},
		],
		selectList: []

	}
}

const state = getDefaultState()
const getters = {
	// 判断是否全选
	checkedAll(state) {
		return state.cartData.length == state.selectList.length;
	}
}
const mutations = {
	// 全选
	checkAll(state) {
		state.selectList = state.cartData.map(v => {
			v.checked = true;
			return v.id
		})
	},
	// 不全选
	unCheckAll(state) {
		state.cartData.forEach(v => {
			v.checked = false;
		})
		console.log(state.cartData);
		state.selectList = [];
	},
	// 单选
	oneCheck(state, index) {
		let id = state.cartData[index].id; // 查询 原数组 id
		let res = state.selectList.indexOf(id); // 原数组的 id 是否存在于空数组 res 返回存在位置
		if (res > -1) {
			state.cartData[index].checked = false;
			return state.selectList.splice(res, 1);
		}
		state.cartData[index].checked = true;
		state.selectList.push(id);;
	}
}
const actions = {
	checkAllFunc({
		commit,
		getters
	}) {
		getters.checkedAll ? commit("unCheckAll") : commit("checkAll")
	}
}

export default {
	state,
	getters,
	mutations,
	actions
}
  • main.js
import App from './App'

// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
import { createApp } from 'vue'
import store from 'store/index.js'
const app = createApp(App)
app.use(store).mount('#app')
// Vue.config.productionTip = false
// #endif

// #ifdef VUE3
import {
	createSSRApp
} from 'vue'
export function createApp() {
	const app = createSSRApp(App)
	return {
		app
	}
}
// #endif
Logo

前往低代码交流专区

更多推荐