【pinia】从0开始的pinia安装与使用

介绍

Pinia是一个Vue的状态管理库,可以用于在应用程序中管理状态。

安装

yarn add pinia 
#or
npm install pinia。

使用

1.在main.js文件中导入Pinia,并将其添加到我们的应用程序中

//main.js
import { createPinia } from 'pinia' 

const pinia = createPinia()
const app = createApp(App)

app.use(pinia).mount('#app')
  1. 创建一个名为ProductStore的存储器,并定义其初始状态和获取器
import { defineStore } from 'pinia'
//const useProductStore = defineStore('product', {}),其中的product为pinia的id,确保唯一性;命名一般使用useXXX,如useProductStore 
export const useProductStore = defineStore('product', {
    state: () => ({
        products: [ Product1,Product2,Product3];
        current:0;
        name:"物品"
    }),
	//类似于computed 可以帮我们去修饰我们的值
    getters: {
        productCount(state) {
            // 获取器可以访问状态
            return state.products.length
        },

        productsCheaperThan(state, price) {
            // 获取器可以接受参数
            return (product) => {
                // 获取器必须返回一个函数而不是一个布尔值
                return product.price < price
            }
        }
    },
    
	//可以操作异步 和 同步提交state
    actions: {
        addProduct(Product) {
            this.products.push(Product)
        }setCurrent () { 
			this.current++   
		}
    }
})

修改state值的几种方法

import {useProductStore} from './store'
const product = useProductStore() 

//1.直接修改,State 是允许直接修改值
const Add = () => { 
	product.current++ 
}
//2.使用$patch修改State的值,$patch方法可以批量修改多个值
const Add = () => {
	product.$patch({  
		current:200, 
		name:"食品" 
	})  
}
//3.批量修改函数形式;推荐使用
const Add = () => {
	product.$patch((state)=>{
		state.current++;
		state.name="食品" 
	})
}
//通过原始对象修改整个实例
//使用$state方法,即:通过将store的属性设置为新对象来替换store的整个状态;缺点:必须修改整个对象的所有属性
const Add = () => {
	Test.$state = {
		current:10,
		name:"食品" 
	}
}
//5.通过action方法修改state的值  
const Add = () => {
	product.setCurrent()
}

然后,我们可以在Vue组件中使用这个存储器。有两种方法可以使用Pinia: Composition API 和 Options API。

对于 Composition API,我们可以在组件的<script setup>块中导入并使用存储器实例

<template>
  <ul>
    <li v-for="product in store.products">{{ product }}</li>
  </ul>
  <p>{{ store.productCount }}</p>
  <ul>
    <li v-for="product in store.productsCheaperThan(10)">{{ product }}</li>
  </ul>
  <button @click="store.addProduct(Product)">Add</button>
</template>

<script setup>
import { useProductStore } from "./stores/ProductStore";
const store = useProductStore();
</script>

对于 Options API,我们可以在组件的<script>块中导入存储器,并使用mapStores函数将其映射到计算属性上:

<template>
  <ul>
    <li v-for="product in productStore.products">{{ product }}</li>
  </ul>
  <p>{{ productStore.productCount }}</p>
  <ul>
    <li v-for="product in productStore.productsCheaperThan(10)">
      {{ product }}
    </li>
  </ul>
  <button @click="productStore.addProduct(Product)">Add</button>
</template>
<script>

import { useProductStore } from "./stores/ProductStore";
import { mapStores } from "pinia";

export default {
  // 导入 mapStores 函数
  setup() {
    // 映射存储器到计算属性上
    return {
      ...mapStores(useProductStore),
      // 计算属性
      someComputed() {
        // 使用存储器中的数据
      },
    };
  },
};
</script>

pinia的API

$reset

$reset,重置store到他的初始状态

// 恢复初始状态
store.$reset()

$subscribe

我们还可以订阅存储器的变化并在变化后执行某些操作:
只要有state 的变化就会走这个函数

store.$subscribe((mutation, state) => {
    console.log(`State changed: ${JSON.stringify(state)}`)
})

$onAction

订阅Actions的调用,只要有actions被调用就会走这个函数

store.$onAction((args)=>{
	console.log(args);
})

【拓展】利用localStorage实现pinia持久化并封装组件

(具体的使用场景我还没有用到,觉得有用,先记录下来)

// src/utils/piniaPlugin.js
import { toRaw } from 'vue'
const setStorage = (key, value) => {
    localStorage.setItem(key, JSON.stringify(value))
}
//存缓存中读取
const getStorage = (key) => {
    return (localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key)) : {})

}
const piniaPlugin = (option) => {
    return (context) => {
        const { store } = context
        const data = getStorage(`${option.key}-${store.$id}`)
        store.$subscribe(() => {
            setStorage(`${option.key}-${store.$id}`, toRaw(store.$state));        
        })
        return {
            ...data
        }
    }
}
export default piniaPlugin
//main.js
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from './App.vue'
import './assets/main.css'
import piniaPlugin from './utils/piniaPlugin.js' // 引入封装好的插件

const pinia = createPinia()
pinia.use(piniaPlugin( { key: "pinia" }))

const app = createApp(App)

app.use(pinia)
.mount('#app')

后续慢慢完善……
参考:
pinia插件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值