目录
一、实例
二、需求
三. 代码解析
shop.vue
shop.ts
四、持久化插件
插件介绍
持久化实现思路
一、实例
二、需求
- 单选全选功能,并且可以互相联动
- 小计功能
- 总计功能
- 商品加减,数量为零时不能在减
三. 代码解析
shop.vue
1.获取shop模块实例
2.updateNum实现商品加减函数
3.allSelectChange 实现全选函数
4.singChange实现单选函数
<template>
<div>我是购物车</div>
<div>全选 <input type="checkbox" v-model="ShopStore.isAllSelect" @change="allSelectChange"></div>
<div v-for="(item,index) in ShopStore.goods" :key="index">
<input @change="singChange" v-model="item.select" type="checkbox" name="" id="">
商品名:{{ item.name }} ----
商品价格:{{ item.price }} ----
<button @click="updateNum(index,1)">+</button>
{{ item.num||1 }}
<button @click="updateNum(index,-1)" >-</button>
小记 {{ item.price*(item.num||1) }}
</div>
<div>总价:{{ ShopStore.total }}</div>
</template>
<script setup lang="ts">
import { userShopStore } from "./store/shop";
const ShopStore = userShopStore()
const updateNum = (index: number, num: number) => {
ShopStore.updateNum(index,num)
}
const allSelectChange = () => {
ShopStore.allSelectChange()
}
const singChange = () => {
ShopStore.singChange()
}
</script>
shop.ts
导入 defineStore函数 interface 定义接口类 导出模块实例
state存放数据 goods商品数组实现接口 isAllSelect全选状态
getters 计算属性。通过filter过滤出选择项 reduce累加计算总计
actions 存放方法
updateNum 加减操作 初始化num 进行数值操作
allSelectChange 每次点击全选,都需要同步单选状态 控制全选
singChange:判断全选状态
import { defineStore } from "pinia";
interface IGoods {
name: string,
price: number,
num?: number,
select?: boolean
}
export const userShopStore = defineStore('shop', {
state() {
return {
goods: [
{
name: '羊肉串',
price: 20
},
{
name: '猪肉串',
price: 15
},
{
name: '鸡翅',
price: 10
}
] as IGoods[],
isAllSelect: false
}
},
getters: {
total(): number {
return this.goods
.filter(item => item.select)
.reduce((total, item) => total += (item.num || 1) * item.price, 0)
}
},
actions: {
updateNum(index: number, num: number) {
//初始化num
this.goods[index].num = this.goods[index].num || 1
//进行数值操作
this.goods[index].num! += num
},
allSelectChange() {
//每次点击全选,都需要同步单选状态
this.goods.forEach((item) => {
item.select = this.isAllSelect
})
},
singChange() {
this.isAllSelect = this.goods.every(item => item.select)
}
}
})
四、持久化插件
插件介绍
Pinia 插件是一个函数,可以选择返回要添加到 store 的属性。 它需要一个可选参数,一个 context:
export function myPiniaPlugin(context) {
context.pinia // 使用 `createPinia()` 创建的 pinia
context.app // 使用 `createApp()` 创建的当前应用程序(仅限 Vue 3)
context.store // 插件正在扩充的 store
context.options // 定义存储的选项对象传递给`defineStore()`
// ...
}
持久化实现思路
监听state的变化,把每次变化的结果放到localStorage里面。初始化的时候回显数据
import { PiniaPluginContext } from "pinia";
export function persistedstate(context: PiniaPluginContext) {
// 初始化回显数据
const shop = JSON.parse(localStorage.getItem(context.store.$id) || "{}");
context.store.$patch(shop);
// 订阅每次state的变化
context.store.$subscribe(
(_mutation, state) => {
localStorage.setItem(_mutation.storeId, JSON.stringify(state));
},
{
detached: true,
}
);
}