如何正确安装 Pinia 商店?

Iva*_*S95 8 javascript state-management vue.js vuex pinia

我正在使用 OptionsAPI 和 Pinia Store 构建一个 Vue 3 应用程序,但我经常遇到一个问题,指出我试图在createPinia()调用之前访问该商店。

我一直在按照文档使用 Pinia 商店外部组件,但也许我没有以正确的方式做事。

情况如下:

我有一个登录屏幕 ( /login),其中有一个 Cognito 会话管理器,我单击一个链接,完成 Cognito 的注册过程,然后重定向到主路由 ( /),在此路由中,我还有一个子路由,显示一个Dashboard组件,其中我进行 API 调用。

在组件上Home,我使用以下方式调用存储useMainStore(),然后在从 Cognito 重定向后使用 URL 上的信息更新状态,然后我想在Dashboard.

这是我的Home组件,它本身工作得很好,因为我想象在创建 Pinia 实例后总是调用的钩子const store = useMainStore();内部。mounted()

<template>
  <div class="home">
    <router-view></router-view>
  </div>
</template>

<script>
import {useMainStore} from '../store/index'

export default {
  name: 'Home',
  components: {
  },
  mounted() {
    const store = useMainStore();

    const paramValues = {}

    const payload = {
      // I construct an object with the properties I need from paramValues
    }

    store.updateTokens(payload); // I save the values in the store
  },
}
</script>
Run Code Online (Sandbox Code Playgroud)

现在这是我的Dashboard组件:

<script>
import axios from 'axios'
import {useMainStore} from '../store/index'

const store = useMainStore();

export default {
    name: "Dashboard",
    data() {
    return {
        user_data: null,
      }
  },
  mounted() {
    axios({
      url: 'myAPIUrl',
      headers: { 'Authorization': `${store.token_type} ${store.access_token}`}
    }).then(response => {
      this.user_data = response.data;
    }).catch(error => {
      console.log(error);
    })
  },
}
</script>
Run Code Online (Sandbox Code Playgroud)

上面的组件将失败,并抛出一个错误,指出我正在尝试在创建实例之前访问存储,我可以通过mounted()像以前一样将存储声明移动到钩子内来解决这个问题,但是如果我想使用以其他方式存储在组件内部而不仅仅是在mounted钩子中?而且,为什么会失败?至此,由于Home组件已经可以访问商店,因此Dashboard位于子路由内的组件不应该Home已经创建了商店实例吗?

这是我main.js调用该createPinia()方法的文件。

<template>
  <div class="home">
    <router-view></router-view>
  </div>
</template>

<script>
import {useMainStore} from '../store/index'

export default {
  name: 'Home',
  components: {
  },
  mounted() {
    const store = useMainStore();

    const paramValues = {}

    const payload = {
      // I construct an object with the properties I need from paramValues
    }

    store.updateTokens(payload); // I save the values in the store
  },
}
</script>
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

Uncaught Error: []: getActivePinia was called with no active Pinia. Did you forget to install pinia?

我的商店文件:

<script>
import axios from 'axios'
import {useMainStore} from '../store/index'

const store = useMainStore();

export default {
    name: "Dashboard",
    data() {
    return {
        user_data: null,
      }
  },
  mounted() {
    axios({
      url: 'myAPIUrl',
      headers: { 'Authorization': `${store.token_type} ${store.access_token}`}
    }).then(response => {
      this.user_data = response.data;
    }).catch(error => {
      console.log(error);
    })
  },
}
</script>
Run Code Online (Sandbox Code Playgroud)

Est*_*ask 4

use这是可能的,但并不常见,而且并不总是允许在组件之外使用组合函数。函数可以依赖于组件实例或特定的执行顺序,如果不遵守它,当前的问题可能会发生。

在使用之前需要创建 Pinia 实例。const store = useMainStore()在导入 Dashboard.vue 时进行评估,这总是发生在 之前createPinia()

对于选项 API,它可以被分配为组件实例的一部分(仅限 Vue 3):

  data() {
    return { store: useMainStore() }
  },
Run Code Online (Sandbox Code Playgroud)

或公开为全局属性(仅限 Vue 3):

const pinia = createPinia();
const app = createApp(App).use(router).use(pinia);
app.config.globalProperties.mainStore = useMainStore();
app.mount('#app');
Run Code Online (Sandbox Code Playgroud)