javascript - menggunakan pinia di luar komponen menyebabkan error no active pinia
Saya sedang mengerjakan proyek Vue.js 3 yang dibangun menggunakan template ViteSse, saya ingin menggunakan salah satu store Pinia saya yang bernama notificationStore di luar komponen setup tetapi saya mendapatkan error getActivePinia called with no active Pinia. Did you forget to install Pinia ketika saya menjalankan perintah dev. Perilakunya sangat aneh karena hal ini tidak terjadi jika saya menambahkan useNotificationStore setelah server dev dimuat dan itu bekerja dengan baik, tetapi ketika useNotificationStore ada di file ts saya dan menjalankan perintah dev, muncul error.
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 })
}
)
Saya telah menelusuri masalah dengan beberapa pencatatan dan menemukan bahwa itu terjadi sebelum createApp dijalankan yang memulai Pinia dan tidak ada Pinia aktif saat itu. Saya mengira createApp di main.ts telah dijalankan sebelumnya semuanya
terima kasih sebelumnya
Jawaban #1
Saya berhasil menyelesaikan masalah dengan membaca dokumentasi dengan cermat:
Cara termudah untuk memastikan ini selalu diterapkan adalah dengan menunda pemanggilan useStore() dengan menempatkannya di dalam fungsi yang akan selalu dijalankan setelah pinia diinstal.
Saya baru saja memperbarui http-client dengan menghapus useNotificationStore() dari bagian atas file dan di mana saya membutuhkan instance notificationStore, gunakan 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 })
}
)
Jawaban #2
ini terjadi karena Anda belum mendaftarkan pinia dengan aplikasi
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
})
},
)
Silakan hapus useOidcStore() di tingkat atas
