目录
一、概念
Pinia是Vue专属的最新的状态管理库,是vuex状态管理工具的替代品
1、提供更简单的API(去掉了Mutation)
2、提供符合组合式风格的API(和Vue3统一)
3、去掉了modules概念,每一个store都是一个独立的模块
4、搭配TS一起使用提供可靠的类型判断
二、配置(具体参照官方文档)
1、使用create-vue创建空的新项目
npm init vue@latest
2、根据文档安装pinia到目录
npm install pinia
3、在main.js中加入代码
import { createPinia } from 'pinia'
const pinia = createPinia()
createApp(App).use(pinia).mount('#app')
三、基本使用(以计数器为例)
在src/stores/counter.js中
import { defineStore, storeToRefs } from 'pinia'
import { computed, ref } from 'vue'
// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id
export const useCounterStore = defineStore('counter',()=>{
// 定义数据State
const count = ref(0)
// 定义方法action=同步+异步
const add = ()=>{
count.value++
}
// 异步action
const list = ref([])
const getList = async()=>{
const res = await axios.get(API_URL)
list.value = res.data.data.channels
}
// getter
const doubleCount = computed(()=>count.value*2)
// 以对象方式return
return{
count,
add,
doubleCount,
list,
getList
}
})
在要使用的组件中
<script setup>
// 导入use开头的方法
import { useCounterStore } from './stores/counter';
// 执行得到store实例对象
const counterStore= useCounterStore()
console.log(counterStore);
</script>
<template>
<div>{{ counterStore.count }}</div>
<button @click="counterStore.add">+1</button>
</template>
<style scoped>
</style>
2、getter的实现
Pinia中getters直接使用computed进行模拟
// getter
const doubleCount = computed(()=>count.value*2)
3、action实现异步
和组件里定义数据风格一致
// 异步action
const list = ref([])
const getList = async()=>{
const res = await axios.get(API_URL)
list.value = res.data.data.channels
}
记得把该return的return出去
4、storeToRefs
使用storeToRefs函数可以辅助保持数据(state+getter)的响应式解构
错误案例(错误的,就放个图了):
<script setup>
// 导入use开头的方法
import { useCounterStore } from './stores/counter';
import { storeToRefs } from 'pinia';
// 执行得到store实例对象
const counterStore= useCounterStore()
console.log(counterStore);
// 解构同时保证不丢失响应式
const {count,doubleCount} = storeToRefs(counterStore)
</script>
<template>
<div>{{ counterStore.count }}</div>
<div>{{ counterStore.doubleCount }}</div>
<div>{{ doubleCount }}</div>
<div>{{ count }}</div>
<button @click="counterStore.add">+1</button>
</template>