0

我正在使用 Vue 3,包括 Composition API 和 Pinia 作为状态管理。

在选项 API 中有一个方法 beforeRouteEnter,它内置在组件本身中。不幸的是,组合 API 中不存在此方法。这里的代码,本来应该在 beforeRouteEnter 方法中,被直接写入到 setup 方法中。但是,这意味着首先加载和显示组件,然后执行代码,如果检查失败,例如,组件将被重定向到错误页面。

我的想法是直接在路由的 beforeEnter 方法中的路由配置中进行检查。但是,我无法访问 Pinia Store,它似乎还没有被初始化,尽管它之前在 main.js 中被调用过。

控制台日志

Uncaught Error: []: getActivePinia was called with no active Pinia. Did you forget to install pinia?
    const pinia = createPinia()
    app.use(pinia)
This will fail in production.

路由器.js

import { useProcessStore } from "@/store/process";

const routes: Array<RouteRecordRaw> = [
{
    path: "/processes/:id",
    name: "ProcessView",
    component: loadView("ProcessView", "processes/"),
    beforeEnter: () => {
      const processStore = useProcessStore();
      console.log(processStore);
    },
    children: [
      {
        path: "steer",
        name: "ProcessSteer",
        component: loadView("ProcessSteer", "processes/")
      },
      {
        path: "approve/:code",
        name: "ProcessApprove",
        component: loadView("ProcessApprove", "processes/")
      }
    ]
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
});

export default router;

main.js

import { createApp } from "vue";
import "@/assets/bundle-bootstrap.css";
import App from "@/App.vue";
import { createPinia } from "pinia";
import router from "@/router";
import SvgIcon from "@/components/SvgIcon.vue";

const pinia = createPinia();
const app = createApp(App);

app.use(pinia);
app.use(router);
app.component("SvgIcon", SvgIcon);

router.isReady().then(() => {
  app.mount("#app");
});

4

2 回答 2

0

但是,我无法访问 Pinia Store,它似乎还没有被初始化,尽管它之前在 main.js 中被调用过

在什么之前?Pinia 实例是在导入模块const pinia = createPinia(); 创建的router——在导入时,包括调用在内的所有副作用都会createRouter()被执行。一旦创建了路由器,它就会开始它的初始导航(在客户端 - 在服务器上,您需要使用 触发它router.push()) - 如果您碰巧在与使用 Pinia 存储的保护的路由匹配的 URL 处,则useProcessStore()在创建 Pinia 之前发生.. .

在组件之外使用存储

你有两个选择:

  • 要么确保在Pinia 创建 ( ) 和安装 ( )之后useXXXStore()发生任何调用createPinia()app.use(pinia)
  • 或者您将 Pinia 实例传递到useXXXStore()组件的任何外部...
// store.js
import { createPinia } from "pinia";

const pinia = createPinia();

export default pinia;
// router.js
import pinia from "@/store.js";
import { useProcessStore } from "@/store/process";

const routes: Array<RouteRecordRaw> = [
{
    path: "/processes/:id",
    name: "ProcessView",
    component: loadView("ProcessView", "processes/"),
    beforeEnter: () => {
      const processStore = useProcessStore(pinia ); // <-- passing Pinia instance directly
      console.log(processStore);
    },
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
});

export default router;
// main.js
import { createApp } from "vue";
import App from "@/App.vue";
import store from "@/store.js";
import router from "@/router";

const app = createApp(App);

app.use(store);
app.use(router);

router.isReady().then(() => {
  app.mount("#app");
});
于 2022-01-14T17:36:12.903 回答
0

您可以在definestore的第二个参数中传递该方法:

store.js

export const useAppStore = defineStore('app', () => {
  const state = reactive({
    appName: 'App',
    appLogo: ''
  })

  return {
    ...toRefs(state)
  }
})

路由器.js

router.beforeEach((to, from, next) => {
  const apppStore = useAppStore()
  next()
})
于 2022-02-05T07:38:18.133 回答