在VueRouter中使用Pinia

3,152 阅读1分钟

2023 年 11 月 15 日更新:

经评论区提醒,使用本文中的方法会导致持久化失效,如果需要持久化,请使用官方示例

2023 年 9 月 18 日更新:

Pinia 官方文档已经给出解决方案:在组件外使用 store | Pinia (vuejs.org)

前言

目前Vue3+Vite+Pinia+VueRouter的组合已经非常流行了,但是在使用过程中也发现了一个小小的问题,即在VueRouter中使用Pinia会报错,后来经过一番研(bai)究(du)找到了解决方法

报错文字:

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.

问题复现

demo结构

代码呈现

//counter.js
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
})


//router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import {useCounterStore} from '@/stores/counter'

const counterStore=useCounterStore()
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('../views/AboutView.vue')
    }
  ]
})

router.beforeEach((to,from)=>{
  console.log(to.name)
  console.log(from.name)
})

export default router

报错提示

初步推测是因为初始化VueRouter的时机比初始化Pinia的时机更早

解决方法

  1. 单独导出pinia 新建了一个pinia.js
//pinia.js
import {createPinia} from 'pinia';

const pinia = createPinia();

export default pinia;

  1. 在引用到store的地方使用pinia.js
//router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import {useCounterStore} from '@/stores/counter'
import pinia from '@/stores/pinia'

const counterStore=useCounterStore(pinia) //在此处传入pinia
const router = createRouter({
......
})

export default router

问题解决!

后记

目前官方文档并没有提供相应的解决方案,目前这个方法不是很优雅,但是能够解决这个问题,期待其他的解决方法!