跳至主要內容

pinia

wangdx大约 3 分钟

准备一个效果

搭建 pinia 环境

第一步:npm install pinia

第二步:操作src/main.ts

import { createApp } from "vue";
import App from "./App.vue";

/* 引入createPinia,用于创建pinia */
import { createPinia } from "pinia";

/* 创建pinia */
const pinia = createPinia();
const app = createApp(App);

/* 使用插件 */ {
}
app.use(pinia);
app.mount("#app");

此时开发者工具中已经有了pinia选项

存储+读取数据

  1. Store是一个保存:状态业务逻辑 的实体,每个组件都可以读取写入它。

  2. 它有三个概念:stategetteraction,相当于组件中的: datacomputedmethods

  3. 具体编码:src/store/count.ts

    // 引入defineStore用于创建store
    import { defineStore } from "pinia";
    
    // 定义并暴露一个store
    export const useCountStore = defineStore("count", {
      // 动作
      actions: {},
      // 状态
      state() {
        return {
          sum: 6,
        };
      },
      // 计算
      getters: {},
    });
    
  4. 具体编码:src/store/talk.ts

    // 引入defineStore用于创建store
    import { defineStore } from "pinia";
    
    // 定义并暴露一个store
    export const useTalkStore = defineStore("talk", {
      // 动作
      actions: {},
      // 状态
      state() {
        return {
          talkList: [
            { id: "yuysada01", content: "你今天有点怪,哪里怪?怪好看的!" },
            { id: "yuysada02", content: "草莓、蓝莓、蔓越莓,你想我了没?" },
            { id: "yuysada03", content: "心里给你留了一块地,我的死心塌地" },
          ],
        };
      },
      // 计算
      getters: {},
    });
    
  5. 组件中使用state中的数据

    <template>
      <h2>当前求和为:{{ sumStore.sum }}</h2>
    </template>
    
    <script setup lang="ts" name="Count">
    // 引入对应的useXxxxxStore
    import { useSumStore } from "@/store/sum";
    
    // 调用useXxxxxStore得到对应的store
    const sumStore = useSumStore();
    </script>
    
    <template>
      <ul>
        <li v-for="talk in talkStore.talkList" :key="talk.id">
          {{ talk.content }}
        </li>
      </ul>
    </template>
    
    <script setup lang="ts" name="Count">
    import axios from "axios";
    import { useTalkStore } from "@/store/talk";
    
    const talkStore = useTalkStore();
    </script>
    

修改数据(三种方式)

  1. 第一种修改方式,直接修改

    countStore.sum = 666;
    
  2. 第二种修改方式:批量修改

    countStore.$patch({
      sum: 999,
      school: "atguigu",
    });
    
  3. 第三种修改方式:借助action修改(action中可以编写一些业务逻辑)

    import { defineStore } from "pinia";
    
    export const useCountStore = defineStore("count", {
      /*************/
      actions: {
        //加
        increment(value: number) {
          if (this.sum < 10) {
            //操作countStore中的sum
            this.sum += value;
          }
        },
        //减
        decrement(value: number) {
          if (this.sum > 1) {
            this.sum -= value;
          }
        },
      },
      /*************/
    });
    
  4. 组件中调用action即可

    // 使用countStore
    const countStore = useCountStore();
    
    // 调用对应action
    countStore.incrementOdd(n.value);
    

storeToRefs

  • 借助storeToRefsstore中的数据转为ref对象,方便在模板中使用。
  • 注意:pinia提供的storeToRefs只会将数据做转换,而VuetoRefs会转换store中数据。
<template>
  <div class="count">
    <h2>当前求和为:{{ sum }}</h2>
  </div>
</template>

<script setup lang="ts" name="Count">
import { useCountStore } from "@/store/count";
/* 引入storeToRefs */
import { storeToRefs } from "pinia";

/* 得到countStore */
const countStore = useCountStore();
/* 使用storeToRefs转换countStore,随后解构 */
const { sum } = storeToRefs(countStore);
</script>

getters

  1. 概念:当state中的数据,需要经过处理后再使用时,可以使用getters配置。

  2. 追加getters配置。

    // 引入defineStore用于创建store
    import { defineStore } from "pinia";
    
    // 定义并暴露一个store
    export const useCountStore = defineStore("count", {
      // 动作
      actions: {
        /************/
      },
      // 状态
      state() {
        return {
          sum: 1,
          school: "atguigu",
        };
      },
      // 计算
      getters: {
        bigSum: (state): number => state.sum * 10,
        upperSchool(): string {
          return this.school.toUpperCase();
        },
      },
    });
    
  3. 组件中读取数据:

    const { increment, decrement } = countStore;
    let { sum, school, bigSum, upperSchool } = storeToRefs(countStore);
    

$subscribe

通过 store 的 $subscribe() 方法侦听 state 及其变化

talkStore.$subscribe((mutate, state) => {
  console.log("LoveTalk", mutate, state);
  localStorage.setItem("talk", JSON.stringify(talkList.value));
});

store 组合式写法

import { defineStore } from "pinia";
import axios from "axios";
import { nanoid } from "nanoid";
import { reactive } from "vue";

export const useTalkStore = defineStore("talk", () => {
  // talkList就是state
  const talkList = reactive(
    JSON.parse(localStorage.getItem("talkList") as string) || []
  );

  // getATalk函数相当于action
  async function getATalk() {
    // 发请求,下面这行的写法是:连续解构赋值+重命名
    let {
      data: { content: title },
    } = await axios.get("https://api.uomg.com/api/rand.qinghua?format=json");
    // 把请求回来的字符串,包装成一个对象
    let obj = { id: nanoid(), title };
    // 放到数组中
    talkList.unshift(obj);
  }
  return { talkList, getATalk };
});

demo


上次编辑于: