setup 语法 <script setup lang="ts"></script>
版本 2.2.4,看官方文档不够直观,这里记录下常见的 api。
如果安装完 pinia 在使用的时候,报 The requested module vue-demi does not provide an export named 'hasInjectionContext' ,需要将 Vue 升级到 3.3.0
接入
main.ts
import { createPinia } from "pinia";
const piniaInstance = createPinia();
createApp(App).use(piniaInstance).mount("#app");
src/store/loginStore.ts 定义
import { defineStore } from "pinia";
const useLoginStore = defineStore("login", {
state() {
return {
username: "小红",
age: 10,
};
},
});
export default useLoginStore;
src/store/index.ts 统一导出
export { default as useLoginStore } from "./loginStore";
state
HellowWorld.vue 使用
<script setup lang="ts">
import { useLoginStore } from "@/store";
"vue";
const loginStore = useLoginStore();
const onChangeName = () => {
loginStore.username = "wx";
};
const onRest = () => {
loginStore.$reset();
};
</script>
<template>
<div @click="onChangeName">{{ loginStore.username }}</div>
<ElButton @click="onRest">重置</ElButton>
</template>
storeToRefs 提取属性同时保持其响应式
const { username } = storeToRefs(loginStore);
可以直接直接修改
loginStore.username = "wx";
$patch 修改
loginStore.$patch({
username: "wx",
});
loginStore.$patch((state) => {
state.username = "wx";
});
$state 替换
loginStore.$state = { username: "wx", age: 20 };
$reset 重置
loginStore.$reset();
$subscribe 监听变化
当组件被卸载时自动删除。
loginStore.$subscribe((mutation, state) => {
console.log(mutation, state);
});
getter
无法向定义的 getter 传递参数,但可以返回一个函数并接受参数
const useLoginStore = defineStore("login", {
state() {
return {
username: "小红",
age: 10,
colorList: ["red", "green", "blue", "orange"],
};
},
getters: {
findColorPostiopn(state) {
return (color: string) =>
state.colorList.findIndex((item) => item === color);
},
},
});
<script setup lang="ts">
import { useLoginStore } from "@/store";
import {
ref,
} from "vue";
const loginStore = useLoginStore();
const index = ref(-1);
const findIndex = () => {
index.value = loginStore.findColorPostiopn("red");
};
</script>
<template>
<div>{{ index }}</div>
<ElButton @click="findIndex">添加</ElButton>
</template>
actions
import { defineStore } from "pinia";
const useLoginStore = defineStore("login", {
state() {
return {
username: "小红",
age: 10,
};
},
actions: {
async increamenAge(age: number) {
return await new Promise((resolve) => {
setTimeout(() => {
this.age += age;
resolve(true);
}, 3000);
});
},
},
});
export default useLoginStore;
<script setup lang="ts">
import { useLoginStore } from "@/store";
const loginStore = useLoginStore();
const onAdd = () => {
loginStore.increamenAge(3);
};
</script>
<template>
<div>{{ loginStore.age }}</div>
<ElButton @click="onAdd">添加</ElButton>
</template>
订阅 actions
loginStore.$onAction(
({
name, // action 的名字
store, // store 实例
args, // 调用这个 action 的参数
after, // 在这个 action 执行完毕之后,执行这个函数
onError, // 在这个 action 抛出异常的时候,执行这个函数
}) => {
// 记录开始的时间变量
const startTime = Date.now();
// 这将在 `store` 上的操作执行之前触发
console.log(`Start "${name}" with params [${args.join(", ")}].`);
// 如果 action 成功并且完全运行后,after 将触发。
// 它将等待任何返回的 promise
after((result) => {
console.log(
`Finished "${name}" after ${
Date.now() - startTime
}ms.\nResult: ${result}.`
);
});
// 如果 action 抛出或返回 Promise.reject ,onError 将触发
onError((error) => {
console.warn(
`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
);
});
}
);
返回函数可用于移除