使用pinia 进行全局的状态管理,降低组件之间的耦合性
一、项目需要的资源
1、element plus官方地址:https://element-plus.gitee.io/zh-CN/guide/quickstart.html
2、pinia 官方地址:https://pinia.web3doc.top/introduction.html
pinia 缓存插件地址:https://prazdevs.github.io/pinia-plugin-persistedstate/guide/
3、vue官方地址:https://cn.vuejs.org/
二、安装插件
1、安装 element plus
npm i element-plus -- save
//or
yarn add element-plus -- save
2、安装pinia 和pinia缓存
npm i pinia --save
//or
yarn add pinia --save
npm i pinia-plugin-persistedstate --save
//or
yarn add pinia-plugin-persistedstate --save
三、应用
1、在main.js 中引入pinia、pinia 缓存以及element plus
import { createApp } from "vue";
import { createPinia } from "pinia";//引入pinia
import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; //pinia 持久化
import App from "./App.vue";
import ElementPlus from "element-plus";//引入element plus
import "element-plus/dist/index.css";//引入element plus 的样式文件
import "default-passive-events";
// import "./assets/main.css";
import "./assets/common.css";
import router from "./router"; // 引入路由
import * as ElementPlusIconsVue from "@element-plus/icons-vue";//引入element plus 中的icon
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate); //pinia数据持久化
const app = createApp(App);
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component);
}
app.use(pinia); //pinia 挂载到vue 实例上
app.use(ElementPlus);//element plus 挂载到vue实例上
app.use(router);//路由 挂载到vue 实例上
app.mount("#app");
2、在src文件夹下创建 store/index.js
import { defineStore } from "pinia";//引入pinia
export const useGoodCarStore = defineStore("goodCar", {
id: "demo",//缓存的key
state: () => ({ count: 0, listArr: [], selectListArr: [] }),
getters: {
double: (state) => state.count * 2,
// 购物车中的总数量
totalNum: (state) => {
let num = 0;
if (state.selectListArr.length > 0) {
num = state.selectListArr.reduce((acc, cur) => {
return acc + cur.num;
}, 0);
}
return num;
},
// 购物车中的总价格
totalPrice: (state) => {
let price = 0;
if (state.selectListArr.length > 0) {
price = state.selectListArr.reduce((acc, cur) => {
return acc + cur.num * cur.price;
}, 0);
}
return price;
},
},
actions: {
increment(state) {
if (this.listArr.length == 0) {
this.listArr.push({
...state,
num: 1,
});
} else {
let index = this.listArr.findIndex((item) => item.id == state.id);
if (index != -1) {
this.listArr[index].num = this.listArr[index].num + 1;
} else {
this.listArr.push({
...state,
num: 1,
});
}
}
console.log("商品数组:", this.listArr);
},
// 选中购物车中的商品
selectGoodCar(state) {
this.selectListArr = state;
},
},
// 开启数据持久化
persist: true,
});
3、创建购物车列表页
>跳转至购物车页面
>
>加入购物车
>
import { onMounted, reactive } from "vue";
import { useRouter } from "vue-router";
import { useGoodCarStore } from "../../store/index"; //引入购物车数据
const store = useGoodCarStore();
console.log("store:", store);
// 实例化路由
const router = useRouter();
const reactiveObj = reactive({
goodArr: [
{
id: 1,
name: "包子",
storeNum: 100,
price: 2,
desc: "皮薄、馅大,十八褶...",
},
{
id: 2,
name: "饺子",
storeNum: 2000,
price: 10,
desc: "露露远远811111",
},
{
id: 3,
name: "鸡蛋灌饼",
storeNum: 20,
price: 6,
desc: "牛牛牛牛牛酷酷酷...",
},
{
id: 4,
name: "馄饨",
storeNum: 10,
price: 3,
desc: "热气腾腾的。。。",
},
],
});
onMounted(() => {
console.log("挂载数据");
});
// 点击 添加购物车按钮
const handleClick = (obj) => {
console.log("加入购物车", obj.row);
// store.$patch({
// count: store.count + 1,
// });
store.increment(obj.row);
console.log("store.count:", store.count);
};
// 跳转至购物车页面
const goToCarPath = () => {
router.push({
path: "/views/goodCarPage",
});
};
.car-btn {
margin-bottom: 10px;
}
4、创建购物车页面
ref="multipleTableRef" :data="carObj.carArr" border style="width: 100%" @selection-change="handleSelectionChange" > v-model.number="scope.row.num" :min="1" :max="scope.row.storeNum" :precision="0" />
共{{ store.totalNum }}
>件商品,共{{ store.totalPrice }}
>元
import { reactive, onMounted, ref } from "vue";
import { useGoodCarStore } from "../../store/index"; //引入购物车数据
const store = useGoodCarStore();
console.log("store:", store);
const multipleTableRef = ref(null);
onMounted(() => {
if (carObj.carArr.length > 0 && store.selectListArr.length > 0) {
let idsArr = store.selectListArr.map((item) => item.id);
//之前购物车中选中的内容的回显
carObj.carArr.map((item) => {
if (idsArr.includes(item.id)) {
multipleTableRef.value.toggleRowSelection(item, true);
} else {
multipleTableRef.value.toggleRowSelection(item, false);
}
});
}
});
const carObj = reactive({
carArr: [],
});
carObj.carArr = store.listArr; //购物车数据
// 选择购物车中的商品
const handleSelectionChange = (val) => {
store.selectGoodCar(val);
};
.sum-container {
padding-top: 10px;
text-align: right;
}
.weight-text {
font-weight: 600;
font-size: 26px;
}
四、运行效果
1、商品列表页,缓存中没有任何数据
图一 商品列表页
2、当点击加入 “购物车页面”,缓存中就添加了刚刚加入的商品信息
图二 加入购物车操作
3、当点击图二中的 “跳转至购物车页面”,页面跳转至购物车列表页
图三 购物车列表页
4、勾选购物车中的商品,计算商品的数量以及商品需花费的总价格
图四 勾选商品,计算商品总数量及总价格
推荐链接
发表评论