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}.`
      );
    });
  }
);
返回函数可用于移除