javascript - bileşen dışında pinia kullanmak aktif pinia hatası oluşturur


ViteSse şablonu kullanılarak oluşturulmuş bir Vue.js 3 projesi üzerinde çalışıyorum, setup bileşeni dışında notificationStore adında Pinia depolarımdan birini kullanmak istiyorum ama dev komutunu çalıştırdığımda getActivePinia called with no active Pinia. Did you forget to install Pinia hatası alıyorum. Davranışı çok garip çünkü dev sunucusu yüklendikten sonra useNotificationStore eklersem bu hata oluşmuyor ve sorunsuz çalışıyor, ancak useNotificationStore ts dosyamda mevcutsa ve dev komutunu çalıştırırsam hata alıyorum.

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 })
  }
)

Sorunu bazı loglamalarla izledim ve bunun, Pinia'yı başlatan createApp çalıştırılmadan önce meydana geldiğini ve o sırada aktif bir Pinia olmadığını gördüm. main.ts içindeki createApp'in her şeyden önce çalıştırılmış olmasını bekliyordum

şimdiden teşekkürler

Cevap #1

Sorunu belgeleri dikkatlice okuyarak çözmeyi başardım:

Bunun her zaman uygulanmasını sağlamanın en kolay yolu, useStore() çağrılarını pinia yüklendikten sonra her zaman çalışacak fonksiyonların içine yerleştirerek ertelemektir.

Dosyanın üstünden useNotificationStore()'u kaldırarak http-client'ı güncelledim ve notificationStore örneğine ihtiyacım olan yerde useNotificationStore().addNotification(...) kullanıyorum.

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 })
  }
)

Cevap #2

bu, pinia'yı uygulama ile kaydetmediğiniz için oluyor

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
    })
  },
)

Lütfen useOidcStore()'u üst seviyede kaldırın