pinia入门

978 阅读1分钟

一、pinia

Pinia 是 Vue 的存储库,它允许跨组件/页面共享状态。

与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的规范,提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。

二、引入pinia

安装:

npm i pinia

main.ts中引入pinia:

import { createPinia } from 'pinia'
app.use(createPinia())

三、定义store:defineStore()

定义store需要使用pinia自带的defineStore()方法,第一个参数为该store的名称:

在根目录创建:./stores/count.ts文件:

import { defineStore } from "pinia";

export const useCounterStore = defineStore('count',{
  state: () => ({
    counter: 1,
  }),
  getters: {
    doubleCount: (state) => state.counter * 2,
  },
  actions: {
    increment() {
      this.counter++;
    },
  },
});

四、使用store

直接使用store.xxx数据无响应式,

为了store中的数据有响应式,需使用storeToRefs()方法对store进行解构。

<template>
  <div class="about">
    <h1>{{ storeCounter }}</h1>
    <h1>{{ counter }}</h1>
    <h1>{{ doubleCount }}</h1>
  </div>
</template>

<script lang="ts" setup>
import { storeToRefs } from "pinia";
import { computed } from "vue";
import { useCounterStore } from "../stores/counter";

const store = useCounterStore();
const storeCounter = store.counter; // 非响应式
const { counter } = storeToRefs(store); // 响应式
setTimeout(() => {
  store.counter++;
}, 3000);
</script>

五、改变state数据

1. store.xxx直接修改

store.xxx直接修改一次只能改变state中一个数据值。

2. 使用$patch()方法修改

使用store.$patch()方法修改:一次可改变state中多个数据值。

<template>
  <div class="about">
    <h1>{{ storeCounter }}</h1>
    <h1>{{ counter }}</h1>
    <div @click="click">{{ name }}</div>
  </div>
</template>

<script lang="ts" setup>
import { storeToRefs } from "pinia";
import { computed } from "vue";
import { useCounterStore } from "../stores/counter";

const store = useCounterStore();
const storeCounter = store.counter; // 非响应式
const { counter, name } = storeToRefs(store); // 响应式

const click = () => {
  store.$patch({
    counter: store.counter + 1,
    name: "John",
  });
};
</script>

六、getter

1. 设置getter:

import { defineStore } from "pinia";

export const useCounterStore = defineStore('main',{
  state: () => ({
    counter: 1,
    name: 'Amy'
  }),
  getters: {
    doubleCount: (state) => state.counter * 2, // 由于没有使用this,会自动进行类型推断
    doubleCountOne(): number { // 这里需要设置类型
      return this.counter * 2 + 1
    },
  }
});

使用:

<template>
  <div class="about">
    <h1>{{ doubleCount }}</h1>
    <h1>{{ doubleCountOne }}</h1>
  </div>
</template>

<script lang="ts" setup>
import { computed } from "vue";
import { useCounterStore } from "../stores/counter";

const store = useCounterStore();
const doubleCount = computed(() => store.doubleCount);
const doubleCountOne = computed(() => store.doubleCountOne);
</script>

2. 设置参数

import { defineStore } from "pinia";

export const useCounterStore = defineStore('main',{
  state: () => ({
    counter: 1
  }),
  getters: {
    countTwo: (state) =>  (num: number) => state.counter * num,
  }
});

使用:

<template>
  <div class="about">
    <h1>{{ countTwo(3) }}</h1>
  </div>
</template>

<script lang="ts" setup>
import { computed } from "vue";
import { useCounterStore } from "../stores/counter";

const store = useCounterStore();
const countTwo = computed(() => store.countTwo);
</script>

3. 访问其他 Store 的getter

新建./stores/user.ts:

import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
    state:()=> ({
        userId: '1134374872347'
    })
})

./store/count.ts中获取user.ts中的userId:

import { defineStore } from "pinia";
import { useUserStore } from './user'
export const useCounterStore = defineStore('main',{
  getters: {
    otherStoreMsg: () => {
      const userStore = useUserStore()
      return userStore.userId
    }
  }
});

七、action

设置action:

import { defineStore } from "pinia";
import {useUserStore} from './user'
export const useCounterStore = defineStore('main',{
  state: () => ({
    counter: 1,
  }),
  actions: {
    increment() {
      this.counter++;
    },
  },
});

使用:

<template>
  <div class="about">
    <div @click="click">{{ counter }}</div>
  </div>
</template>

<script lang="ts" setup>
import { storeToRefs } from "pinia";
import { useCounterStore } from "../stores/counter";

const store = useCounterStore();
const { counter } = storeToRefs(store); // 响应式

const click = () => {
  store.increment();
};
</script>