微信公众号
扫描关注微信公众号
博客大厅

如何在组件中使用 Pinia store?

原创 来源:博客站 阅读 0 03月22日 07:17 听全文

在组件中使用 Pinia Store 非常简单。Pinia 提供了直观的 API,使得在组件中访问和操作 Store 的状态、getters 和 actions 变得非常容易。以下是详细的使用步骤:


1. 安装 Pinia

如果你还没有安装 Pinia,可以通过以下命令安装:

npm install pinia

2. 创建并定义 Store

首先,你需要定义一个 Store。例如,定义一个简单的计数器 Store:

// stores/counter.js
import { defineStore } from 'pinia';

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

3. 在组件中使用 Store

访问 State

在组件中,你可以通过 useStore 函数获取 Store 实例,并直接访问 state

<template>
  <div>
    <p>Count: {{ counterStore.count }}</p>
  </div>
</template>

<script>
import { useCounterStore } from '@/stores/counter';

export default {
  setup() {
    // 获取 Store 实例
    const counterStore = useCounterStore();

    return {
      counterStore, // 将 Store 实例暴露给模板
    };
  },
};
</script>

使用 Getters

getters 可以直接通过 Store 实例访问,就像访问普通属性一样。

<template>
  <div>
    <p>Double Count: {{ counterStore.doubleCount }}</p>
  </div>
</template>

<script>
import { useCounterStore } from '@/stores/counter';

export default {
  setup() {
    const counterStore = useCounterStore();

    return {
      counterStore,
    };
  },
};
</script>

调用 Actions

actions 可以通过 Store 实例直接调用。

<template>
  <div>
    <p>Count: {{ counterStore.count }}</p>
    <button @click="counterStore.increment">Increment</button>
    <button @click="counterStore.incrementAsync">Increment Async</button>
  </div>
</template>

<script>
import { useCounterStore } from '@/stores/counter';

export default {
  setup() {
    const counterStore = useCounterStore();

    return {
      counterStore,
    };
  },
};
</script>

4. 使用组合式 API

如果你使用 Vue 3 的组合式 API,可以在 setup 函数中直接使用 Store。

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
    <button @click="incrementAsync">Increment Async</button>
  </div>
</template>

<script>
import { useCounterStore } from '@/stores/counter';
import { computed } from 'vue';

export default {
  setup() {
    const counterStore = useCounterStore();

    // 将 state 和 getters 转换为响应式引用
    const count = computed(() => counterStore.count);
    const doubleCount = computed(() => counterStore.doubleCount);

    // 直接调用 actions
    function increment() {
      counterStore.increment();
    }

    function incrementAsync() {
      counterStore.incrementAsync();
    }

    return {
      count,
      doubleCount,
      increment,
      incrementAsync,
    };
  },
};
</script>

5. 在模板中直接解构 Store

如果你希望在模板中直接使用 Store 的属性或方法,可以使用 storeToRefs 工具函数将 Store 转换为响应式引用。

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
    <button @click="incrementAsync">Increment Async</button>
  </div>
</template>

<script>
import { useCounterStore } from '@/stores/counter';
import { storeToRefs } from 'pinia';

export default {
  setup() {
    const counterStore = useCounterStore();

    // 使用 storeToRefs 将 state 和 getters 转换为响应式引用
    const { count, doubleCount } = storeToRefs(counterStore);

    // 直接调用 actions
    const { increment, incrementAsync } = counterStore;

    return {
      count,
      doubleCount,
      increment,
      incrementAsync,
    };
  },
};
</script>

6. 在组件外使用 Store

如果你需要在组件外使用 Store(例如在工具函数或 API 请求中),可以直接导入并使用 Store。

import { useCounterStore } from '@/stores/counter';

export function someUtilityFunction() {
  const counterStore = useCounterStore();
  counterStore.increment();
}

总结

在组件中使用 Pinia Store 的步骤如下:

  1. 使用 defineStore 定义 Store。
  2. 在组件中通过 useStore 获取 Store 实例。
  3. 直接访问 stategetters 和调用 actions
  4. 可以使用组合式 API 或 storeToRefs 来简化代码。

Pinia 的设计使得状态管理变得非常简单和直观,适合各种规模的 Vue 3 项目。

学在每日,进无止境!更多精彩内容请关注微信公众号。
原文出处: 内容由AI生成仅供参考,请勿使用于商业用途。如若转载请注明原文及出处。
出处地址:http://www.07sucai.com/tech/830.html
版权声明:本文来源地址若非本站均为转载,若侵害到您的权利,请及时联系我们,我们会在第一时间进行处理。
>