1、Pinia是什么呢?
Pinia 是一个用于 Vue 的状态管理库,可以说是Vuex的替代品, 尤大神强势推荐
2、优势在哪里?
- Vue2 和 Vue3 都支持
- 更小,只有1KB
- 不需要嵌套模块,符合Vue3的Composition api,让代码更加扁平化
- 抛弃了Mutations的操作,只有state、getters和actions.极大简化了状态管理库的使用
- 完整的TypeScript支持
- 代码更加简洁,可以实现很好的代码自动分割
3、安装
# 使用yarn
yarn add pinia
# 使用npm
npm install pinia
4、使用
创建Pinia(根存储)并将其传递到应用程序
还记得Vuex在使用时一般采用modules方式,这就需要在store/index.ts中将所有的modules通过creaeStore注册到store中,那么Pinia就省去了这些麻烦,createPinia()即可,不需要注册modules,没有任何参数,所以连store/index.ts都可以不用了,直接在main.ts中添加即可, 这一点会比Vuex简洁很多
import { createPinia } from 'pinia'
app.use(createPinia());
# main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
定义Store
定义store的函数式defineStore,这就很有Vue3的风格, 还需要一个唯一的store id,定义Store有以下两种方式:
1、选项式定义
# src/stores/counter.ts
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 10
}),
actions: {
increment() {
this.count++
}
}
})
2、函数式定义 类似于component setup()方式,这种方式更符合Vue3,个人比较喜欢这种定义方式
# src/stores/counter.ts
import { ref } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const count = ref(10)
const increment = () => {
count.value++
}
return { count, increment }
})
至于Getters, 在Pinia如同computed一样,所有是否需要完全取决于项目的需要
使用Store
这里需要用到storeToRefs提取属性,来保持属性的响应性
# src/components/HelloWorld.vue
<template>
<div>count = {{ count }}</div>
<button @click="onClick">Increment</button>
</template>
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/stores/counter'
const counterStore = useCounterStore()
const { count } = storeToRefs(counterStore)
const onClick = () => {
counterStore.increment()
}
</script>
5、总结
Pinia要比Vuex简洁很多,也更容易理解,这也正是Pinia设计的初衷,更符合直觉,个人觉得函数式的定义Store特别好,再也不需要记录那些state,getter,actions了,开发者可以更专注于业务逻辑的开放,Pinia还有很多的用户和细节,请转官方文档[Home | Pinia (vuejs.org)](