pinia踩坑之旅——在组件外使用pinia

pinia踩坑之旅------在组件外使用pinia

缘由

最近在使用 pinia 开发项目时产生了一个 bug,说在定义 pinia 前使用了 pinia。

报错如下:

代码展示

先来看一个我的代码(这里我新开了一个项目用于演示),如果懒得看代码的可以直接跳过看代码说明。

js 复制代码
// main.js

import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'

const app = createApp(App).use(createPinia()).mount('#app')
vue 复制代码
<!-- App.vue -->

<template>
  <div>{{ countStore.count }}</div>
  <button @click="add">点击+1</button>
</template>

<script setup>
import useCountStore from "./stores/count.js";
import add from "./utils/add.js";

const countStore = useCountStore();
</script>
js 复制代码
// stores/count.js

import { defineStore } from 'pinia';

export default defineStore('count', {
  state: () => ({
    count: 0
  }),
  actions: {
    add: function () {
      this.count++;
    }
  }
})
js 复制代码
// utils/add.js

import useCountStore from '../stores/count.js'

const countStore = useCountStore()

export default function () {
  countStore.add();
}

代码说明

这里我在 utils 目录下创建了一个 js 文件用于定义一个工具函数,而这个工具函数需要用到 pinia 中的一个 action,此时就产生了报错。

报错分析

这里报错我在引入 pinia 前使用了 pinia。

我的第一反应时是不是我忘写 use(pinia) 了,然后我去 main.js 看了代码,发现我确实引入了 pinia,这时我就很疑惑为什么我引用了 pinia 却报错说我没引入。

没办法,只能详细看了一下报错,在最后一行显示 at add.js:3:20,说明我们的工具函数文件有问题,但是在组件中也是这样引入的,没有问题,这时就陷入了迷茫,不知道哪里有问题了。

没办法,只能去官网看一下有没有相关的解释了。

查阅官网 - 找出原因

官网 - 指南 - 核心概念这里额外写了一个组件外的 Store,先看看和组件内使用有什么区别。

这里有一句话引起了我的注意:

scss 复制代码
在 setup() 中,你不需要再做任何事情。但在组件之外,情况就有点不同了。实际上,useStore() 给你的 app 自动注入了 pinia 实例。这意味着,如果 pinia 实例不能自动注入,你必须手动提供给 useStore() 函数。

解释一下:

其实 useStore() 是需要传入 pinia 实例的,但是在 setup() 中已经自动注入了 pinia 实例,所以即使你不传入任何参数也能正常使用,但是在组件外属于非 setup(),这时就需要老老实实的按规矩调用人家的 API 了。

解决问题

既然已经找到了原因,现在就差解决问题了,即我需要在 add.js 中引入 pinia 实例并作为参数进行传递。

此时又出现了一个问题,之前为了简写代码,根本没有将 pinia 实例用变量进行保存,所以现在的代码实现不了这一点。

为了让以后遇到类似的问题都能够更好的解决,决定在 stores 目录下创建一个入口文件 index.js 专门用于导出 pinia 实例。

js 复制代码
// stores/index.js

import { createPinia } from 'pinia'

const pinia = createPinia();

export default pinia;
js 复制代码
// main.js

import { createApp } from 'vue'
import App from './App.vue'
import pinia from './stores/index.js'

const app = createApp(App).use(pinia).mount('#app')
js 复制代码
// utils/add.js

import pinia from '../stores/index.js'
import useCountStore from '../stores/count.js'

const countStore = useCountStore(pinia)

export default function () {
  countStore.add();
}

现在,在组件外就能正常使用 pinia 了。

总结

我们在使用一项不熟悉的技术时往往都是去网上找一篇使用文章看下用法就上手了,这么做的好处时能够最快速的上手在项目中进行使用,但是这类文章往往只会把基本的用法进行描述,而不会把一些坑点说出来,如果在使用时恰好遇到了就非常棘手。

我推荐三种我日常使用的比较多的解决办法,以及各自的优缺点:

  1. 百度

    没错,你没有看错,就是百度,就是这么朴实无华。

    把报错复制到百度直接搜结果,如果不是一些比较冷门或者先进的技术问题都能搜得到。

    优点:速度最快

    缺点:网上资料质量参差不全,容易遇到一些 ly 文章很耗费时间

  2. 官网

    优点:去翻官网不仅仅可以解决遇到的问题,还能学习到这项技术更多的东西。

    缺点:比较耗时,需要有耐心去找

  3. 问群友

    相信大家都多多少少有那么两、三个技术群,问群友说不定有在这方面有研究的群友能够解答你的问题,甚至还能给你讲为什么,当然,这个就看人了。

    优点:运气好群友不仅能解决问题,还能跟你说为什么会出现这个问题

    缺点:运气差没有人鸟就很尴尬

最后还是提一下,遇到问题时一定要先自己尝试去解决,不要一遇到就问人,确实解决不了再去问别人是否有这一方面的研究。

相关推荐
你挚爱的强哥2 小时前
✅✅✅【Vue.js】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本
javascript·vue.js·jquery
y先森2 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy2 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189112 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿3 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡4 小时前
commitlint校验git提交信息
前端
天天进步20155 小时前
Vue+Springboot用Websocket实现协同编辑
vue.js·spring boot·websocket
虾球xz5 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇5 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒5 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript