个人简介
个人主页: 前端杂货铺
♂️学习方向: 主攻前端方向,正逐渐往全干发展
个人状态: 研发工程师,现效力于中国工业软件事业
人生格言: 积跬步至千里,积小流成江海
推荐学习:前端面试宝典 Vue2 Vue3 Vue2/3项目实战 Node.jsThree.js JS版算法
个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧
内容 | 参考链接 |
---|---|
Vue3正式发布那么久了,你认识Pinia了吗? | 认识Pinia,搭建开发环境 |
Pinia 核心概念 | 核心概念(Store、State、Getter、Action) |
各位新朋友、老朋友们大家好,这里是前端杂货铺,欢迎各位的到来!!
上篇文章 我们学习了 Store、State、Getter、Action 的概念以及基本的使用。实践出真知,这篇文章我们通过以上所学知识实现一个简单的购物车功能。
shop.vue
该组件用于构建UI,搭建基本的页面结构。所有的属性和方法我们放在 Pinia 中去管理。
全选和单选的联动,我们使用断言返回的 true/false 进行判断。
<template>
<div>
<h3 style="color: orange">前端杂货铺的购物车</h3>
</div>
<div>全选 <input type="checkbox" v-model="shopStore.isAllSelect" @change="allSelectChange"></div>
<div>
<div v-for="(item, index) in shopStore.goods" :key="index">
<input type="checkbox" @change="singleChange" v-model="item.select">
【商品】:<span style="color:red">{{ item.name }}</span> --
【价格】:<span style="color:pink">{{ item.price }}</span>¥ --
<button @click="updateNum(index, 1)">+</button>
<span style="color: blue">{{ item.num || 1 }}</span>【件】
<button @click="updateNum(index, -1)">-</button>
【小计】:<span style="color:brown">{{ item.price * (item.num || 1) }}</span>
</div>
</div>
<div>
总价 {{ shopStore.total }}
</div>
</template>
<script setup lang="ts">
import { useShopStore } from './store/shop';
const shopStore = useShopStore();
const updateNum = (index: number, num: number) => {
shopStore.updateNum(index, num);
}
const allSelectChange = () => {
shopStore.allSelectChange();
}
const singleChange = () => {
shopStore.singleChange();
}
</script>
./store/shop.ts
把数据状态存放到 state 中,在这里我们存放了 “啤酒” 、“饮料”、“泉水”,以及全选的属性。在 shop.vue 中的属性也是在该文件中定义的,我们先定义了接口(Interface),之后在合适的位置进行相应的使用。
注意函数和参数等进行相应的类型限制。
import { defineStore } from 'pinia'
// 接口
interface IGoods {
name: string
price: number
num?: number // 默认没有
select?: boolean // 默认没有
}
export const useShopStore = defineStore('shop', {
state() {
return {
goods: [
{
name: '啤酒',
price: 5
},
{
name: '饮料',
price: 4
},
{
name: '泉水',
price: 2
},
] 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) {
this.goods[index].num = this.goods[index].num || 1
// -! 会告诉编译器,xx肯定不是 null 或 undefined
this.goods[index].num! += num
},
allSelectChange() {
this.goods.forEach(item => {
item.select = this.isAllSelect
})
},
singleChange() {
this.isAllSelect = this.goods.every(item => item.select)
}
}
})
main.ts
导入创建 Shop 并使用 pinia,最后挂载到 #app
import { createApp } from 'vue'
import './style.css'
import pinia from './store'
import Shop from './shop.vue'
createApp(Shop).use(pinia).mount('#app')
./store/index.ts
导入 pinia,创建实例并暴露出去
import { createPinia } from 'pinia'
const pinia = createPinia()
export default pinia
终端键入:npm run dev,在浏览器打开即可
这是一篇很简单的文章。“麻雀虽小,五脏俱全”。我们构建 购物车 案例,就是为了巩固我们前两节所学的知识,使得我们对 Pinia 状态管理库有一个更加清晰的认识。
好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!
参考资料:
- Pinia 官方文档
- Pinia 教程 【作者:千锋教育】