相比较于Vuex,Pinia抛弃了Mutation操作,保留state,getters,actions,并且支持Typescript和Vue3的组合式Api。
yarn add pinia
// 或者
npm install pinia
store/index
// index.ts文件下
import { createPinia} from 'pinia'
// 实例化,也可以在main.ts文件中实例化,我习惯写在这是为了更好定位问题
const store = createPinia()
export default store
main.ts
文件中挂载store
实例import { createApp } from 'vue'
import App from './App.vue'
// Pinia
import store from './store'
const app = createApp(App).use(store)
defineStore
import { createPinia, defineStore } from 'pinia'
const store = createPinia()
// 每一个存储的模块,命名规则use开头,store结尾
// defineStore提供两个参数,第一个参数为数据的id,第二参数接受一个对象(书写配置项)
export const useAuthStore = defineStore('auth', {
state: () => {
return {
num: 0
}
},
getters: {},
actions: {},
})
export default store
export const useAuthStore = defineStore('auth', () => {
const num= ref(0)
function increment() {
num.value++
}
return { num, increment }
})
// ref() 就是 state 属性
// computed() 就是 getters
// function() 就是 actions
<template>
<div>
<h2>{{ store.num }}</h2>
</div>
</template>
<script setup lang="ts">
import { useAuthStore } from "../store/index";
const store = useAuthStore();
</script>
storeToRefs
来做响应式数据<template>
<div>
<h2>{{ store.num }}</h2>
</div>
</template>
<script setup lang="ts">
import { useAuthStore } from "../store/index"
import { storeToRefs } from 'pinia'
const store = useAuthStore();
// 这样结构出来的数据是响应式的
const { num } = storeToRefs(store)
// 如果直接结构store实例,数据只能使用一次
</script>
在Vuex中,提供mutation来修改state数据。在Pinia数据模块中,可直接修改state数据,并且提供
$patch
来修改多条数据。虽然我们可以不用$patch
就修改多条数据,但是Pinia提供的$patch
让我们修改数据更加高效,相当于性能优化。
// $patch接收两个参数类型,对象和函数
<script setup lang="ts">
// $patch + 对象
const store = useAuthStore()
const change = () => {
store.$patch({
doubleCount: store.num * 2
moreCount: store.num++
})
}
// $patch + 函数
const store = useAuthStore()
const change = () => {
store.$patch((state) => {
state.num++
state.count--
})
}
</script>
注意!$patch
不接收异步函数
跟Vuex的getters概念相差不多,也是state的计算属性,并且可以通过
this
访问store
实例
export const useStore = defineStore('main', {
state: () => ({
count: 0,
}),
getters: {
//官方推荐使用箭头函数
doubleCount:(state) => state.count *2,
// getters之间相互引用
doublePlusOne(): number {
return this.doubleCount + 1
},
// 引用其他store的getters
otherGetter(state) {
const otherStore = useOtherStore()
return state.localData + otherStore.data
},
},
})
跟getters一样,可以通过
this
访问store
实例,可用于接收异步函数
import { mande } from 'mande'
const api = mande('/api/users')
export const useUsers = defineStore('users', {
state: () => ({
userData: null,
// ...
}),
actions: {
async registerUser(login, password) {
try {
this.userData = await api.post({ login, password })
showTooltip(`Welcome back ${this.userData.name}!`)
} catch (error) {
showTooltip(error)
// 让表单组件显示错误
return error
}
},
},
// 也可以访问其他store的actions,具体操作参照上文getters
})