- 安装npm i pinia
- 导入
import { createPinia} from 'pinia'
- 注册
app.use(createPinia())
使用
import { defineStore } from 'pinia'
export const useMainStore = defineStore('main', {
state: () => {
return {
count: 100
}
},
getters: {
counter10 (state) {
return state.count + 10
}
},
actions: {
incrementCount (a: string, b: number) {
setTimeout(() => {
this.count++
}, 1000)
}
}
})
<template>
<h2>Counter A</h2>
<p>{{ mainStore.count }}</p>
<p>{{ mainStore.counter10 }}</p>
<p>
<button @click="handleChangeState">修改 state 数据</button>
</p>
</template>
<script setup lang="ts">
import { useMainStore } from '../store/index'
const mainStore = useMainStore()
const handleChangeState = () => {
mainStore.incrementCount('a', 10)
}
</script>
<template>
<ul>
<li v-for="item in all">
{{ item.title }} - {{ item.price }}
<br />
<button
:disabled="!item.inventory"
@click="cartStore.addProductToCart(item)"
>添加到购物车</button>
</li>
</ul>
</template>
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { useProductsStore } from '../store/products'
import { useCartStore } from '../store/cart'
const productsStore = useProductsStore()
const cartStore = useCartStore()
productsStore.loadAllProducts()
const { all } = storeToRefs(productsStore)
console.log(all.value)
</script>
import { defineStore } from 'pinia'
import { getProducts, IProduct } from '../api/shop'
export const useProductsStore = defineStore('products', {
state: () => {
return {
all: [
{ id: 1, title: 'xxx', price: 10, inventory: 100 }
] as IProduct[]
}
},
getters: {},
actions: {
async loadAllProducts () {
const ret = await getProducts()
this.all = ret
},
async decrementProduct (product: IProduct) {
const p = this.all.find(item => item.id === product.id)
if (p) {
p.inventory--
}
}
}
})
<template>
<div class="cart">
<h2>你的购物车</h2>
<p>
<i>请添加一些商品到购物车.</i>
</p>
<ul>
<li v-for="item in cartStore.cartProducts">{{ item.title }} - {{ item.price }} x {{ item.quantity }}</li>
<!-- <li>商品名称 - 商品价格 x 商品数量</li>
<li>商品名称 - 商品价格 x 商品数量</li> -->
</ul>
<p>商品总价: {{ cartStore.totalPrice }}</p>
<p>
<button @click="cartStore.checkout">结算</button>
</p>
<p v-show="cartStore.checkoutStatus">结算{{ cartStore.checkoutStatus }}.</p>
</div>
</template>
<script setup lang="ts">
import { useCartStore } from '../store/cart'
const cartStore = useCartStore()
</script>
export interface IProduct {
id: number
title: string
price: number
inventory: number
}
const _products: IProduct[] = [
{ id: 1, title: 'iPad 4 Mini', price: 500.01, inventory: 2 },
{ id: 2, title: 'H&M T-Shirt White', price: 10.99, inventory: 10 },
{ id: 3, title: 'Charli XCX - Sucker CD', price: 19.99, inventory: 5 }
]
export const getProducts = async () => {
await wait(100)
return _products
}
export const buyProducts = async () => {
await wait(100)
return Math.random() > 0.5
}
async function wait(delay: number) {
return new Promise((resolve) => setTimeout(resolve, delay))
}
import { defineStore } from 'pinia'
import { IProduct, buyProducts } from '../api/shop'
import { useProductsStore } from './products'
type CartProduct = {
quantity: number
} & Omit<IProduct, 'inventory'>
export const useCartStore = defineStore('cart', {
state: () => {
return {
cartProducts: [] as CartProduct[],
checkoutStatus: null as null | string
}
},
getters: {
totalPrice (state) {
return state.cartProducts.reduce((price, item) => {
return price + item.quantity * item.price
}, 0)
}
},
actions: {
addProductToCart(product: IProduct) {
this.checkoutStatus = null
if (product.inventory <= 0) {
return
}
const item = this.cartProducts.find(p => p.id === product.id)
if (item) {
item.quantity++
} else {
this.cartProducts.push({
id: product.id,
title: product.title,
price: product.price,
quantity: 1
})
}
const productsStore = useProductsStore()
productsStore.decrementProduct(product)
},
async checkout () {
this.checkoutStatus = null
const ret = await buyProducts()
if (ret) {
this.checkoutStatus = '成功'
this.cartProducts = []
} else {
this.checkoutStatus = '失败'
}
}
}
})