Pinia是什么?
💡 Pinia是一个Vue的全局状态管理库,它允许您在组件/页面之间共享状态。类似于Vuex, 是Vue3 推荐的另一种全局状态管理方案。
Pinia相比于Vuex有什么优势?
- Vue2和Vue3都支持。
- 不需要嵌套模块, 抛弃vuex中的modules。
- 符合Vue3中的组合式API(composition API), 让代码更加扁平化。
- 完整的支持TypeScript。
- 有利于代码自动分割。
- 代码更简洁明了。
Pinia如何使用?
创建实例
import { createPinia } from 'pinia'
app.use(createPinia())
定义Store
Pinia有两种使用方式: 选项式和组合式。
- 选项式
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
counter: 66,
name: 'pinia'
}),
actions: {
increment: () => {
this.counter++
}
}
})
- 组合式API
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const counter = ref(0)
function increment() {
counter.value++
}
return { counter, increment }
})
使用store
// 组件内使用
import { useCounterStore } from '@/stores/counter'
export default {
setup() {
const store = useCounterStore()
// 1. 可以直接修改
store.counter++
// 2. 通过内置api修改
store.$patch({ count: store.counter + 1 })
// 3. 使用自定义方法修改
store.increment()
},
}
请注意: store是一个响应式对象, 这就意味着不需要.value获取. 但是也想props一样, 我们不能直接对其解构. 为了解构时仍保持其响应性, 你需要使用pinia中的内置方法storeToRefs()。
import { storeToRefs } from 'pinia'
const store = useStore()
const { counter, increment } = storeToRefs(store)
State
改变状态
- 直接使用store改变
store.counter++
- 调用$patch方法改变(允许多个状态同时改变)
store.$patch({
counter: store.counter + 1, // 或者直接赋值 count: 88
name: 'Space'
})
- 定义state时自定义对应的修改方法
重置状态
你可以通过调用store上的方法将状态重置为其初始值: $reset()。
const store = useStore()
// 将store中的状态重置到初始状态
store.$reset()
更换状态
你可以通过调用store的属性$state, 可以用新对象替换整个store状态。
store.$state = {
counter: 88,
name: 'Tab'
}
Getter
Getter完全等同于Store状态的计算值computed.。
定义getter
export const useStore = defineStore('main', {
state: () => {
counter: 0
},
getter:{
doubleCount: (state) => state.counter * 2,
tripleCount(state) {
return state.counter * 3
}
}
})
使用getter
export default {
setup() {
const store = useStore()
console.log(store.doubleCounter)
return {
doubleCounter: store.doubleCounter
}
}
}
Actions
Actions相当于组件中的方法。 他们可以使用actions属性进行定义, defineStore适合定义业务逻辑。
同时支持异步同步操作(async, await, Promise, fetch)。
类似于Vuex中的actions和mutations。
定义actions
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
actions: {
increment() {
this.counter++
},
async fetchCounter(num){
const res = await getCounter()
this.counter = res.data.counter
}
},
})
使用actions
export default {
setup() {
const store = useStore()
store.increment()
}
}