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. 问群友

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

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

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

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

相关推荐
橙光成长32 分钟前
PDF离线工具箱深度解析:4MB纯前端单文件,40+功能全本地运行,文件绝不上传
前端·pdf·1024程序员节
小poop7 小时前
CSS 基础与实战:从入门到精通网页美化
前端
Csvn9 小时前
运行时性能
前端
Never_every999 小时前
位图转矢量工具哪个好?实测抠抠图AI位图转矢量工具
大数据·前端
paopaokaka_luck10 小时前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
空中湖10 小时前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
欣欣之王来了12 小时前
原始HTML插值:v-html指令的使用与安全风险
前端·学习·架构·项目·vue3教程
IT_陈寒12 小时前
Redis的LRU淘汰策略坑了我一整天
前端·人工智能·后端
计算机魔术师12 小时前
砍半价格、参数再涨,国产旗舰追到 Opus 鼻尖了
前端
paopaokaka_luck12 小时前
心理咨询管理系统(WebSocket实时沟通、基于用户的协同过滤、 ECharts多维分析、 预约业务流程、预约校验与定时处理)
java·vue.js·spring boot·mysql·spring·echarts·1024程序员节