Actions:
Actions是pinia和Vuex封装函数逻辑的对象,作用是可以让我们在组件中直接调用,简化了状态管理的过程。Action可以写成同步的,也可以写成异步,其中的函数还可以相互调用
import { defineStore } from 'pinia'
import { Names } from './store-name'
type User = {
name: string
message: string
}
export const useTestStore = defineStore(Names.TEST, {
state: () => {
return {
// 这里采用了给对象属性限制类型的写法
user: <User>{
name: '飞机',
message: '666',
},
}
},
// computed一些值
getters: {},
// 相当于methods,可以做同步、异步操作、提交state等
actions: {
// 最简单的Action,直接在组件中调用即可
setCurrent() {
this.user.message = 'message被改变了'
},
},
})
<template>
<div>user:{{ Test.user }}</div>
<hr />
<div>name:{{ Test.name }}</div>
<button @click="change">change</button>
</template>
<script setup lang="ts">
import { useTestStore } from './Store'
import { storeToRefs } from 'pinia'
const Test = useTestStore()
// 直接来一个Test.setCurrent调用
const change = () => {
Test.setCurrent()
}
</script>
<style scoped></style>
一个异步调用的例子:将异步方法使用Promise封装在defineStore外,通过async……await方法等待Promise响应数据返回
import { defineStore } from 'pinia'
import { Names } from './store-name'
type User = {
name: string
message: string
}
const login = (): Promise<string> => {
return new Promise((resolve) => {
setTimeout(() => {
resolve('模拟异步I/O请求,等待两秒钟执行')
}, 2000)
})
}
export const useTestStore = defineStore(Names.TEST, {
state: () => {
return {
user: <User>{
name: '飞机',
message: '666',
},
name: '开枪',
}
},
// computed一些值
getters: {},
// 相当于methods,可以做同步、异步操作、提交state等
actions: {
async setCurrent() {
let result = await login()
this.user.message = result
},
},
})
<template>
<div>user:{{ Test.user }}</div>
<hr />
<div>name:{{ Test.name }}</div>
<button @click="change">change</button>
</template>
<script setup lang="ts">
import { useTestStore } from './Store'
import { storeToRefs } from 'pinia'
const Test = useTestStore()
const change = () => {
Test.setCurrent()
}
</script>
<style scoped></style>
除此之外,Action中的方法也可以通过this互相调用,以下给出一个示例
import { defineStore } from 'pinia'
import { Names } from './store-name'
type User = {
name: string
message: string
}
const login = (): Promise<string> => {
return new Promise((resolve) => {
setTimeout(() => {
resolve('模拟异步I/O请求,等待两秒钟执行')
}, 2000)
})
}
export const useTestStore = defineStore(Names.TEST, {
state: () => {
return {
user: <User>{
name: '飞机',
message: '666',
},
name: '开枪',
}
},
// computed一些值
getters: {},
// 相当于methods,可以做同步、异步操作、提交state等
actions: {
setMessage() {
this.name = '挡枪'
},
async setCurrent() {
this.setMessage()
let result = await login()
this.user.message = result
},
},
})
getters:
getters相当于计算属性,可以将state中的值做一些“加工”后返回,需要注意的是getters和computed一样都是直接访问,不能调用的(get访问器?)
import { defineStore } from 'pinia'
import { Names } from './store-name'
type User = {
name: string
message: string
}
const login = (): Promise<string> => {
return new Promise((resolve) => {
setTimeout(() => {
resolve('模拟异步I/O请求,等待两秒钟执行')
}, 2000)
})
}
export const useTestStore = defineStore(Names.TEST, {
state: () => {
return {
user: <User>{
name: '飞机',
message: '666',
},
name: '开枪',
}
},
// computed一些值
getters: {
newName(): string {
return `${this.name}通过计算属性获得`
},
// 箭头函数没有this,需要额外传入一个参数state来获取或修改值
getUserName: (state): string => {
return `${state.user.name}通过计算属性获得`
},
},
// 相当于methods,可以做同步、异步操作、提交state等
actions: {
// setMessage中有getters里的属性
setMessage() {
this.name = this.newName
this.user.name = this.getUserName
},
async setCurrent() {
let result = await login()
this.user.message = result
this.setMessage()
},
},
})
请注意,getters实际上有两种写法(如上图所示),一种是普通函数的写法,还有一种是箭头函数。普通函数中如果要访问state可以直接来一个this.state中的属性名,缺点是必须标明函数的返回类型。而箭头函数由于没有this(this为undefined),需要在参数中额外传入一个state,通过state.属性名的方式进行修改。这里我们更推荐箭头函数的写法
<template>
<div>user:{{ Test.user }}</div>
<hr />
<div>name:{{ Test.name }}</div>
<hr>
<div>UserName:{{ Test.user.name }}</div>
<button @click="change">change</button>
</template>
<script setup lang="ts">
import { useTestStore } from './Store'
import { storeToRefs } from 'pinia'
const Test = useTestStore()
const change = () => {
Test.setCurrent()
}
</script>
<style scoped></style>