pnpm create vite
yarn add pinia
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const pinia = createPinia()
const app=createApp(App)
app.use(pinia).mount('#app')
defineStore()
,并且它需要一个唯一的名称,作为第一个参数传递)新建store/main.ts
import { defineStore } from 'pinia'
export const mainStore = defineStore('main',{
state:()=>{
return {
count:100,
price:250
}
},
getters:{
doubleCount():number{
return this.count*2
},
doublePrice():number{
return this.price*2
}
},
actions:{
changeStoreData(){
this.count+=1
this.price+=1
},
}
})
{{ msg }}
数量
pinia-count数据{{count}}
pinia- getters-2倍数量{{doubleCount}}
价格
pinia-price数据{{price}}
pinia- getters-2倍价格{{doublePrice}}
改变数据
新建store/use.ts模块
import { defineStore } from 'pinia'
import { ElLoading } from 'element-plus'
type Res = {
nickname:string,
age:number
}
const Login = ()=>{
return new Promise((resolve,reject)=>{
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
setTimeout(() => {
resolve({
nickname:'张三',
age:22
})
loading.close()
}, 5000);
})
}
export const userStore = defineStore('user',{
state:()=>{
return {
nickname:'',
age:0
}
},
getters:{
},
actions:{
async getUserInfo(){
const res = await Login();
this.nickname=res.nickname;
//this.age=res.age;
//调用其他actions
this.setAge(res.age)
},
setAge(age:number){
this.age=age
}
}
})
用户组件
昵称{{nickname}}--年龄{{age}}
获取用户信息
getters 可以互相调用 普通函数形式可以使用this 使用箭头函数不能使用this this指向已经改变指向undefined 修改值请用state
getters:{
doubleCount():number{
//return this.count*2
return this.doublePrice*2
},
doublePrice:(state)=>state.price*2
},
store
到他的初始状态) 重置数据
const resetData =()=>{
main.$reset()
}
main.$subscribe((args,state)=>{
console.log(args,state,'数据改变')
})
第二个参数
如果你的组件卸载之后还想继续调用请设置第二个参数
main.$subscribe((args,state)=>{
console.log(args,state,'数据改变')
},{
detached:true
})
main.$onAction((args)=>{
console.log(args,'action调用');
})
cnpm i pinia-plugin-persist --save
import { createPinia } from 'pinia'
//pinia 持久化插件
import piniaPluginPersist from 'pinia-plugin-persist'
const store = createPinia()
store.use(piniaPluginPersist)
export default store
import { createApp } from 'vue'
import App from './App.vue'
import 'element-plus/dist/index.css'
import store from './store/index';
import piniaPluginPersist from 'pinia-plugin-persist';
store.use(piniaPluginPersist)
const app=createApp(App)
app.use(store).mount('#app')
import { defineStore } from 'pinia'
import { ElLoading } from 'element-plus'
type Res = {
nickname:string,
age:number
}
const Login = ()=>{
return new Promise((resolve,reject)=>{
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
setTimeout(() => {
resolve({
nickname:'张三',
age:22
})
loading.close()
}, 5000);
})
}
export const userStore = defineStore('user',{
state:()=>{
return {
nickname:'',
age:0
}
},
getters:{
},
actions:{
async getUserInfo(){
const res = await Login();
this.nickname=res.nickname;
//this.age=res.age;
//调用其他actions
this.setAge(res.age)
},
setAge(age:number){
this.age=age
}
},
persist:{
enabled:true,
strategies:[
{
storage:localStorage,paths:['nickname']
}
]
}
})
/**
* src/api/shop.ts
* Mocking client-server processing
*/
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(1000)
return _products
}
export const buyProducts = async () => {
await wait(1000)
return Math.random() > 0.5
}
/**
* 封装了Promise版本的定时器
* @param delay 延迟时间
* @returns Promise
*/
async function wait(delay:number) {
return new Promise(resolve => setTimeout(resolve, delay))
}
-
商品名称:{{item.title}}--
商品价格:{{item.price}}
商品库存:{{item.inventory}}
添加到购物车
我的购物车
- 商品名称:=:{{ item.title }} - 商品价格:{{ item.price }} × 商品数量:{{ item.num }}
请添加一些商品到购物车
商品总价: {{ totalPrice }}
import { defineStore } from "pinia"
import { getProducts, IProduct } from "../api/shop"
export const useProdunctsStore = defineStore('products', {
state: () => {
return {
all: [] as IProduct[] // 所有商品列表(学习类型断言的使用)
}
},
getters: {},
actions: {
//actions既支持异步操作
async loadAllProducts() {
const ret = await getProducts()
this.all = ret
},
// 也支持同步操作
decrementProduct(product: IProduct) {
const ret = this.all.find(item => item.id === product.id)
if (ret) {
ret.inventory--
}
}
}
})
import { defineStore } from "pinia";
import { buyProducts, IProduct } from "../api/shop";
import { useProdunctsStore } from "./products";
/**
* {id, title, price, quantity}
*/
type CartProduct = { // 合并
num: number
} & Omit // Omit是过滤
export const useCartStore = defineStore('cart', {
state: () => {
return {
cartProducts: [] as CartProduct[],
checkoutStatus: null as null | string
}
},
getters: {
// 总价
totalPrice(state) {
return state.cartProducts.reduce((total, item) => {
return total + item.price * item.num
}, 0)
}
},
actions: {
/**
* 往购物车添加商品
* 这是一个相对复杂的逻辑,与容器中的数据强相关,所以肯定要定义在actions里面!
* @param product 需要添加的商品
*/
addProductToCart(product: IProduct) {
// 先看商品有没有库存
if (product.inventory <= 0) {
return
}
// 检查购物车中是否已有该商品
const cartItem = this.cartProducts.find(item => item.id === product.id)
// 如果有则让商品数量+1
if (cartItem) {
cartItem.num++
} else {
// 如果没有则添加到购物车列表中
this.cartProducts.push({
id: product.id,
title: product.title,
price: product.price,
num: 1
})
}
// 跟新商品库存(应该由商品容器暴露API)
const productsStore = useProdunctsStore()
productsStore.decrementProduct(product)
// 跨容器通信!!!!!竟然如此简单!!!
},
/**
* 结算
*/
async checkOut() {
const ret = await buyProducts()
this.checkoutStatus = ret ? '成功' : '失败'
if (ret) {
this.cartProducts = [] // 清空购物车
}
}
}
})