Pinia(发音为/piːnjʌ/,如英语中的“peenya”)是最接近piña(西班牙语中的菠萝)的词;Pinia开始于大概2019年,最初是作为一个实验为Vue重新设计状态管理,让它用起来像组合式API(Composition API)。从那时到现在,最初的设计原则依然是相同的,并且目前同时兼容Vue2、Vue3,也并不要求你使用Composition API;Pinia本质上依然是一个状态管理的库,用于跨组件、页面进行状态共享(这点和Vuex、Redux一样);
和Vuex相比,Pinia有很多的优势:比如mutations 不再存在:更友好的TypeScript支持,Vuex之前对TS的支持很不友好;不再有modules的嵌套结构:也不再有命名空间的概念,不需要记住它们的复杂关系;
使用Pinia
安装依赖
npm install pinia
创建一个pinia并且将其传递给应用程序:
我们新建一个文件夹叫stores,后续pinia相关文件都放入这个文件夹中,创建index.js
import { createPinia } from 'pinia'
const pinia = createPinia()
export default pinia
在main.js中引入使用
import { createApp } from 'vue'
import App from './App.vue'
import pinia from './stores'
createApp(App).use(pinia).mount('#app')
这样pinia就引入了我们的app中,可以开始使用了
认识Store
一个 Store (如 Pinia)是一个实体,它会持有为绑定到你组件树的状态和业务逻辑,也就是保存了全局的状态;它有点像始终存在,并且每个人都可以读取和写入的组件;你可以在你的应用程序中定义任意数量的Store来管理你的状态;
Store有三个核心概念:state、getters、actions;
state用来存储数据,可以直接访问修改,getters类似computed,actions类似于methods,可以直接调用
定义一个Store
在stores文件夹下新建counter.js
import {defineStore} from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => {
return {
count: 0,
banners: [],
recommends: []
}
},
getters: {
doubleCount(state) {
return state.count * 2
}
},
actions: {
async fetchHomeMultidata() {
const res = await fetch("http://123.207.32.32:8000/home/multidata")
const data = await res.json()
this.banners = data.data.banner.list
this.recommends = data.data.recommend.list
return 'ok'
}
}
})
使用store,useCounterStore是个函数,调用后可以返回一个store对象,里面可以直接使用state,getters和actions,其中state可以直接访问和修改,getters可以作为属性来使用,actions是作为方法来调用的,返回promise
<template>
<div class="home">
<h2>count: {{ counterStore.count }}</h2>
<h2>count: {{ counterStore.doubleCount }}</h2>
<button @click="changeState">修改state</button>
<h2>轮播的数据</h2>
<ul>
<template v-for="item in counterStore.banners">
<li>{{ item.title }}</li>
</template>
</ul>
</div>
</template>
<script setup>
import {useCounterStore} from '@/stores/counterStore';
// useCounterStore是一个函数
const counterStore = useCounterStore()
// actions返回的是promise
counterStore.fetchHomeMultidata().then(res => {
console.log(res)
})
function changeState() {
// state可以直接访问和修改
counterStore.count++
}
</script>