• vue3 + pinia实现简单购物车功能


    这个小例子是学习vue3与pinia状态管理工具时写的一个简单的购物车功能,

    它实现了从模拟接口(node.js的json-server提供)读取商品数据,到添加商品到购物车和购物车中删除商品等购物车主要功能

    准备工作,执行 npm i pinia -G 安装pinia

    执行 npm json-server  安装node.js的json工具

    执行 json-server ./src/data/api.json -p 9000 //运行定义好的json文件 及访问端口

        "pinia": "^2.0.22",
        "vue": "^3.2.37",
    <template>
        <div>
            <h1>产品列表</h1>
            <hr>
            <ul>
                <li v-for="item,index in producets" class="shop-box">
                    <div><img :src="IphoneImg"/></div>
                    <div>{{item.name}} -- ¥{{item.price}}  库存:{{item.inventory}}</div>
                    <div><button @click="addToCart(item)" :disabled="item.inventory <= 0">加入购物车</button></div>
                </li>
            </ul>
            <Cart></Cart>
        </div>
    </template>
    
    <script setup>
     import { ref, onMounted } from 'vue';
     import IphoneImg from '../../../public/vite.svg'
     import {storeToRefs} from 'pinia'
     import Cart from './Cart.vue'
     import useProducetStore from '@/store/producetStore';
     import useCartStore from '@/store/cartStore'
     const producetStore = useProducetStore()
     const { producets } = storeToRefs(producetStore)
     const {addToCart} = useCartStore()
     onMounted(()=>{
        producetStore.loadData()
     })
    </script>
    
    <style lang="css">
    .shop-box{
    
    }
    .shop-box div{
        display: inline;
        margin: 0 10px;
    }
    </style>
    <template>
        <div v-if="cartList.length > 0 && cartStore.toAllPrice > 0">
            <h2>购物车</h2>
            <hr>
            <ul>
                <template v-for="item in cartList">
                    <li v-if="item.quantity >= 1" class="car-shop">
                        {{item.name}} ¥{{item.price}} x <button @click="reduceToCartClick(item)" :disabled="item.quantity < 1">-</button><input type="number" :value="item.quantity" @input="handlechange" /><button @click="addToCartClick(item)" :disabled="item.inventory <= 0">+</button> = ¥{{item.price * item.quantity}}
                    </li>
                </template>
            </ul>
            <hr>
            <h4 class="all">总价:¥{{cartStore.toAllPrice}}</h4>
        </div>
    </template>
    
    <script setup>
    import {storeToRefs} from 'pinia'
    import useCartStore from '@/store/cartStore';
    import useProducetStore from '@/store/producetStore';
    const producetStore = useProducetStore()
    const { producets } = storeToRefs(producetStore)
    
    const cartStore = useCartStore()
    const { addToCart, reduceToCart } = useCartStore()
    const {cartList} = storeToRefs(cartStore)
    
    const handlechange = (e)=>{
        // console.log('--->',e.target.value)
    }
    const reduceToCartClick = (p)=>{
        reduceToCart(p)
        producetStore.updateProduces(p)
    }
    const addToCartClick = (p) =>{
        addToCart(p)
        producetStore.updateProduces(p)
    }
    </script>
    
    <style lang="css">
    .car-shop{
    
    }
    .car-shop button{
        margin: 0 5px;
        cursor: pointer;
    }
    .all{
        text-align: right;
        color: red;
    }
    </style>
    import { defineStore } from "pinia";
    import axios from 'axios'
    const useProducetStore = defineStore('producetStore', {
        state() {
            return {
                producets: []
            }
        },
        actions: {
            async loadData() {
                //安装一个node服务工具来模拟接口功能 //npm i json-server -g
                //json-server查看工具命令
                //json-server ./src/data/api.json -p 9000 //运行定义好的json文件 及访问端口
                //http://localhost:9000/data   浏览器中通过该地址访问定义好的json数据
                let result = await axios.get('http://localhost:9000/data')
                // console.log('data---->', result.data)
                this.producets = result.data
    
                // axios.post('http://localhost:9000/data', '{id: 5, name: "iphone15", price: 1200,inventory:2}')
                //json-server服务可以通过post请求向json插入一条数据,但每次个性json数据后需求重启服务才能更新页面数据
            },
            updateProduces(producet) {
                const p = this.producets.find((item)=>{
                    return item.id === producet.id
                })
                if(p){
                    p.inventory = producet.inventory
                }
            }
        }
    })
    export default useProducetStore
    import {defineStore} from 'pinia'
    
    const useCartStore = defineStore('cartStore', {
        state() {
            return {
                cartList: []
            }
        },
        actions: {
            addToCart(producet){
                // console.log('producet--->', producet)
                const p = this.cartList.find((item)=>{
                    return item.id === producet.id
                })
                if(p){
                    p.quantity ++
                    const cartProduct = producet.hasOwnProperty('quantity')
                    if (!cartProduct) {
                        p.inventory --
                    }
                } else {
                    let inventory = producet.inventory
                    inventory --
                    this.cartList.push({
                        ...producet,
                        inventory: inventory,
                        quantity: 1 //购物车里商品数量+1
                    })
                }
                producet.inventory --
            },
            reduceToCart(producet){
                // console.log('reduce--->', producet)
                const p = this.cartList.find((item)=>{
                    return item.id === producet.id
                })
                if(p){
                    p.quantity --
                    p.inventory ++
                    if (p.quantity < 1) {
                        let newCartList = new Set(this.cartList)
                        newCartList.delete(producet)
                        this.cartList = [...newCartList]
                    }
                }
            }
        },
        getters: { //pinia的计算属性
            toAllPrice(){
                return this.cartList.reduce((sum, item)=>{
                    sum += item.price * item.quantity
                    return sum
                },0)
            }
        }
    })
    export default useCartStore
    {
        "data": [
            {
                "id": 1,
                "name": "iphone11",
                "price": 3000,
                "inventory": 3
            },
            {
                "id": 2,
                "name": "iphone12",
                "price": 5000,
                "inventory": 3
            },
            {
                "id": 3,
                "name": "iphone13",
                "price": 8000,
                "inventory": 6
            },
            {
                "id": 4,
                "name": "iphone14",
                "price": 10000,
                "inventory": 2
            }
        ]
    }
  • 相关阅读:
    MERGE同步
    SqlServer中decimal(numeric )、float 和 real 数据类型的区别
    Hashtable
    SQL Server 数据类型 float, real, money, decimal, numeric
    QA常见面试问题答与问(English)zt
    MSDN 代码审查
    security testing
    SQL Server:无日志恢复数据库
    SQL Server 2005 数据库快照(database Snapshot)
    备份和恢复概述zt
  • 原文地址:https://www.cnblogs.com/zhixi/p/16791819.html
Copyright © 2020-2023  润新知