首页 > 其他分享 >vue3 + pinia实现简单购物车功能

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

时间:2022-10-14 15:56:06浏览次数:43  
标签:producet const 购物车 item json inventory pinia vue3 import

这个小例子是学习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
        }
    ]
}

 

标签:producet,const,购物车,item,json,inventory,pinia,vue3,import
From: https://www.cnblogs.com/zhixi/p/16791819.html

相关文章

  • vue3 + qiankun(微前端)
    主服务路由配置constrouter=createRouter({history:createWebHistory(),routes:[{path:`/jupiter:page*`,name:`jupiter`,compo......
  • vite vue3 规范化与Git Hooks
    在《JS模块化》系列开篇中,曾提到前端技术的发展不断融入很多后端思想,形成前端的“四个现代化”:工程化、模块化、规范化、流程化。在该系列文章中已详细介绍了模块化的发......
  • 电子表格也能做购物车?简单三步就能实现
    在我们的项目当中,经常需要添加一些选择界面,让用户直观地进行交互,比如耗材、办公用品、设计稿或者其它可以选择的内容。在线商城的商品目录和购物车无疑是一种大家都很熟悉......
  • uniapp-vue3-ts实现 微信小程序-视频上下滑动
    公司需求,后端被迫学习...临时记录一下后续完善暂时不会组件式开发,只能采用选项式了<template><viewstyle="color:white;"><viewclass="swiper">......
  • Vue3+Element-plus 报错记录
    目录Vue3+Element-plus报错记录报错信息错误场景还原问题排查错误代码el-select多选Vue3+Element-plus报错记录报错信息TypeError:Cannotreadpropertiesofnull......
  • Session用法案例 -->实现简单购物车功能(实际项目可能不会这么使用)
    071201709091、session是在cookie的基础之上,利用cookie返回JSESSIONID(key[服务器随机生成])存在客户端实现,正真的数据存在服务端[key-value]。2、se......
  • vue3+vite引入插件unplugin-auto-import
    自动引入compositionapi,不需要再手动引入。github地址:https://github.com/antfu/unplugin-auto-import下载npmiunplugin-auto-import-D修改vite.config.ts文件i......
  • vue3 父子组件通信
    1.props父组件传参不变,子组件接收: <p>{{props.abc}}</p> <p>{{props.msg}}</p> constprops=defineProps({msg:{type:String,required:......
  • vue3插槽变化
    1.默认插槽还是跟以前一样 2.使用具名插槽时,子组件不变以前的父组件掉用的时候<templateslot="example"></template>现在为<templatev-slot:exam......
  • Vite + Vue3 + Pinia + es6 + TypeScript 搭建项目
    vite中文参考文档:​​https://vitejs.cn/guide/#scaffolding-your-first-vite-project​​执行 npminitvite@latest步骤如下图:下载依赖npmi 启动项目:npmrundev......