Vue3状态管理库Pinia——实现简易版购物车

个人简介

个人主页: 前端杂货铺
‍♂️学习方向: 主攻前端方向,正逐渐往全干发展
个人状态: 研发工程师,现效力于中国工业软件事业
人生格言: 积跬步至千里,积小流成江海
推荐学习:前端面试宝典 Vue2 Vue3 Vue2/3项目实战 Node.jsThree.js JS版算法
个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧

Pinia

内容 参考链接
Vue3正式发布那么久了,你认识Pinia了吗? 认识Pinia,搭建开发环境
Pinia 核心概念 核心概念(Store、State、Getter、Action)

文章目录

  • Pinia
    • ✨✨前言
    • ✨✨Pinia 实战购物车
    • 本篇小结


✨✨前言

各位新朋友、老朋友们大家好,这里是前端杂货铺,欢迎各位的到来!!

上篇文章 我们学习了 Store、State、Getter、Action 的概念以及基本的使用。实践出真知,这篇文章我们通过以上所学知识实现一个简单的购物车功能。


✨✨Pinia 实战购物车

  • 单选全选,并可以互相联动(全选勾上,单选自动全勾上。单选全勾上,全选自动勾上)
  • 小计(当前商品单价 * 当前商品数量)
  • 总计(所有商品的小计之和)

Vue3状态管理库Pinia——实现简易版购物车_第1张图片


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 状态管理库有一个更加清晰的认识。


好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!


参考资料:

  1. Pinia 官方文档
  2. Pinia 教程 【作者:千锋教育】

在这里插入图片描述


你可能感兴趣的:(Pinia,Vue3)