Pinia是什么
pinia是Vue官方团队推荐代替Vuex的一款轻量级状态管理库。Vue3 组合式API出现后,为了更好的支持组合式API,pinia出现了。
Pinia的优势
- 同时支持Vue2.x和Vue3.x
- 完整的 TypeScript 支持:与在 Vuex 中添加 TypeScript 相比,添加 TypeScript 更容易
- 支持多个Store,更利于代码分割
安装
yarn add pinia
或使用npm
npm install pinia
安装完成后,需要创建一个pinia实例并传递给应用。
在main.js或main.ts中
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia'
const pinia = createPinia()
let app = createApp(App)
app.use(pinia)
app.mount('#app')
创建store
我们在src下新建一个store(名字可自定义)文件夹
在文件夹下新建index.ts文件
创建store需要使用defineStore()函数,在index.ts中引入
defineStore() 的第一个参数要求是一个独一无二的名字,
这个名字 ,也被用作 id ,是必须传入的, Pinia 将用它来连接 store 和 devtools。为了养成习惯性的用法,将返回的函数命名为 use… 是一个符合组合式函数风格的约定
第二个参数可接受两类值:Setup 函数或 Option 对象。
import { defineStore } from 'pinia'
export const useStore = defineStore('main',{
state:() => {
return {
current: 1,
}
},
})
然后我们就可以在组件中使用了
<template>
<div>
hello world
pinia: {{ Test.current }}
<button @click="change">change</button>
</div>
</template>
<script setup lang='ts'>
import { useStore } from '../store'
import { ref, reactive } from 'vue'
const Test = useStore()
const change = () => {
Test.current ++
}
</script>
state
stete可以理解为是store的数据。
在上面的例子中,我们在创建store实例时传入了一个包含state的对象,state中的内容就是store的数据。
Getter
Getter 完全等同于 store 的 state 的计算值。可以通过 defineStore() 中的 getters 属性来定义它们。推荐使用箭头函数,并且它将接收 state 作为第一个参数。
我们在store实例中加入getters
export const useStore = defineStore('main',{
state:() => {
return {
current: 1,
name: 'xiaoming'
}
},
getters: {
newName:(state) => {
return 'name_' + state.current
}
},
})
访问其他getter
export const useStore = defineStore('main',{
state:() => {
return {
current: 1,
name: 'xiaoming'
}
},
getters: {
newName:(state) => {
return 'name_' + state.current
},
newNameTwo:(state) => {
return this.newName
},
},
})
通过this我们可以访问到其他任何getters。
下面我们来看看如何来使用getters
使用方法和使用state中的数据一致,在模版中实例化后可以直接获取使用
<template>
<div>
pinia: {{ Test.newName }}
</div>
</template>
<script setup lang='ts'>
import { useStore } from '../store'
const Test = useStore()
</script>
Actions
Action 相当于组件中的 method。它们可以通过 defineStore() 中的 actions 属性来定义,在action中同步和异步方法都可以使用。
type User= {
name: string,
age: number
}
const Login = ():Promise<User> => {
return new Promise((resolve) => {
setTimeout(()=> {
resolve({
name: '大炮',
age: 66
})
},2000)
})
}
export const useStore = defineStore('main',{
state:() => {
return {
current: 1,
name: 'xiaoming'
}
},
actions: {
// 同步方法设置cruuent数据
setCurrent(num:number) {
this.current = num
},
// 异步获取数据,更改user
async setUser() {
const result = await Login()
this.user = result
}
}
})
在模版中使用actions
<script setup lang='ts'>
import { useStore } from '../store'
import { ref, reactive } from 'vue'
const Test = useStore()
const change = () => {
Test.setCurrent(123)
Test.setUser()
}