javascript - pinian käyttö komponentin ulkopuolella aiheuttaa virheen 'ei aktiivista pinia'


Työskentelen Vue.js 3 -projektissa, joka on rakennettu käyttämällä ViteSse-mallia. Haluan käyttää yhtä Pinia-stooreistani nimeltä notificationStore setup-komponentin ulkopuolella, mutta saan virheen getActivePinia called with no active Pinia. Did you forget to install Pinia kun suoritan dev-komennon. Sen käyttäytyminen on todella outoa, koska tätä ei tapahdu, jos lisään useNotificationStorein vasta sen jälkeen, kun dev-palvelin on ladattu, ja silloin se toimii hyvin. Mutta kun useNotificationStore on olemassa ts-tiedostossani ja suoritan dev-komennon, se aiheuttaa virheen.

http-client.ts:

import type { AxiosInstance, AxiosRequestConfig } from 'axios'
import axios from 'axios'
import tokenService from './token.service'
import { useNotificationsStore } from '~/store/notification.store'
const notification = useNotificationsStore()
const httpClient: AxiosInstance
  = axios.create({
    baseURL: `${import.meta.env.VITE_APP_API_URL}/`,
    headers: {
      'Content-Type': 'application/json',
    },
  })


httpClient.interceptors.response.use(
  (response) => {
    if (response.config.method !== 'get') {
      const successMsg = 'operation successfully completed'
      notification.addNotification({ type: 'success', message: successMsg })
    }
    return response
  },
  (error) => {
    if (error.message === 'Network Error') {
      notification.addNotification({ type: 'error', message: 'Network Error' })
      return Promise.reject(error)
    }
    let errorMessage = ''
    const validationErrors = getValidationErrors(error)
    errorMessage = getErrorMessage(error)
    notification.addNotification({ type: 'error', message: errorMessage, validationErrors, hideAfterRouting: false })
  }
)

Olen jäljittänyt ongelmaa jonkin lokituksen avulla ja löytänyt, että se tapahtui ennen createAppin suorittamista, joka käynnisti Pinian, eikä tuolloin ollut aktiivista Piniaa. Olin odottanut, että createApp main.ts:ssä olisi suoritettu ennen kaikkea muuta

kiitos etukäteen

Vastaus #1

Onnistuin ratkaisemaan ongelman lukemalla dokumentaatiota huolellisesti:

Helpoin tapa varmistaa, että tätä sovelletaan aina, on lykätä useStore()-kutsujen tekemistä sijoittamalla ne funktioihin, jotka suoritetaan aina sen jälkeen, kun pinia on asennettu.

Päivitin juuri http-clientin poistamalla useNotificationStore() tiedoston alusta ja siellä, missä tarvitsen notificationStore-instanssin, käytän useNotificationStore().addNotification(...)

import type { AxiosInstance, AxiosRequestConfig } from 'axios'
import axios from 'axios'
import tokenService from './token.service'

const httpClient: AxiosInstance
  = axios.create({
    baseURL: `${import.meta.env.VITE_APP_API_URL}/`,
    headers: {
      'Content-Type': 'application/json',
    },
  })

httpClient.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    const token = tokenService.getLocalAccessToken()
    if (token && config.headers)
      config.headers.Authorization = `Bearer ${token}`

    return config
  },
  (error) => {
    return Promise.reject(error)
  },
)
httpClient.interceptors.response.use(
  (response) => {
    if (response.config.method !== 'get') {
      const successMsg = 'operation successfully completed'
       useNotificationsStore().addNotification({ type: 'success', message: successMsg })
    }
    return response
  },
  (error) => {
    if (error.message === 'Network Error') {
       useNotificationsStore().addNotification({ type: 'error', message: 'Network Error' })
      return Promise.reject(error)
    }
    let errorMessage = ''
    const validationErrors = getValidationErrors(error)
    errorMessage = getErrorMessage(error)
    useNotificationsStore().addNotification({ type: 'error', message: errorMessage, validationErrors, hideAfterRouting: false })
  }
)

Vastaus #2

tämä tapahtuu, koska et ole rekisteröinyt piniaa sovellukseen

export const createApp = ViteSSG(
  App,
  { routes, base: import.meta.env.BASE_URL },
  async (ctx) => {
    Object.values(import.meta.glob<{ install: UserModule }>('./modules/*.ts', { eager: true }))
      .forEach(i => {
        i.install?.(ctx)
      })

// install pinia 
    const pinia = createPinia()
    ctx.app.use(pinia)

    if (import.meta.env.SSR)
      ctx.initialState.pinia = pinia.state.value
    else
      pinia.state.value = ctx.initialState.pinia || {}
// ============

    const DEFAULT_TITLE = 'Dashboard'
    ctx.router.beforeEach((to) => {
// ====== use store ====
      const { state } = useOidcStore()

      if (!store.ready)
        // perform the (user-implemented) store action to fill the store's state
        store.initialize()
// ===========
      if (!state.value.user) {
        autoAuthenticate()
      }
      let title = DEFAULT_TITLE
      if (to.meta.title)
        title = `${to.meta.title} - ${title}`

      document.title = title
    })
  },
)

Poista useOidcStore() ylimmällä tasolla