I'm currently working on a Promise-based modal component that allows for specifying a component as the body of the modal itself. My approach to achieving this was by using a dynamic component inside the modal template. However, when working within a NUXT application, I encountered an issue where referencing the Vuex instance (this.$store) resulted in it being undefined. The same problem occurred with any injections made inside plugins, leading to undefined attributes like $api. If the component is used in a 'standard' way—such as placing it directly inside a page or another component template—everything works fine.
It seems there might be some additional injection steps required before passing the component programmatically. Can anyone offer assistance?
The simplified structure of the NUXT project:
- /pages/index.vue
- /plugins/api.js
- /store/auth.js
- /components/HelloComponent.vue
/plugins/api.js
let api = {}
api.call = function (request, auth, unpack, axios = this.axios) {
if (!request) Error('backend.js:call invalid params:', request, auth, unpack, axios)
if (auth) {
if (request.headers)
request.headers['Authorization'] = 'Bearer ' + this.auth.accessToken
else
request.headers = { 'Authorization': 'Bearer ' + this.auth.accessToken }
}
return axios(request).then((response) => unpack ? response.data : response)
}
api.getAPI = function (api, params, auth = true, unpack = true) {
if (!api) Error('api.js:getAPI invalid params:', api)
console.log('api.js:getAPI api:', api)
return this.call({ method: 'get', url: api, params: params }, auth, unpack)
}
api.postAPI = function (api, params, data, auth = true, unpack = true) {
if (!api) Error('api.js:postAPI invalid params:', api, data)
console.log('api.js:postAPI api:', api)
return this.call({ method: 'post', url: api, params: params, data: data }, auth, unpack)
}
/*******************************************************/
/* NUXT plugin and reference injection */
/*******************************************************/
export default function (context, inject) {
console.log('[CALL] api.js')
/* assign global $axios instance */
api.axios = context.$axios
/* assign auth instance to access tokens */
api.auth = context.store.state.auth
/* inject backend reference into application instance */
inject('api', api)
}
/pages/index.vue
<template>
<div>
<span>
{{ $store.auth.state.name }} // -> Displays 'Chuck'
</span>
/* Object.keys(this).includes('$store): false'; Object.keys(this).includes('$auth): true' */
<component :is="cComponent" /> // -> this.$store is undefined; auth: undefined
<hello-component /> // -> Displays 'Chuck'; auth: Object {...}
</div>
</template>
<script>
import HelloComponent from '../components/HelloComponent.vue'
export default {
components: {
HelloComponent
},
created () {
this.$store.commit('auth/setName', 'Chuck')
},
computed: {
cComponent () {
return HelloComponent
}
}
}
</script>
/components/HelloComponent.vue
<template>
<span>
{{ $store.auth.state.name }}
</span>
</template>
<script>
export default {
created() {
console.log('auth:', this.$auth)
}
}
</script>
/store/auth.js
export const state = () => ({
accessToken: null,
refreshToken: null,
name: null,
})
export const mutations = {
setAccessToken(state, token) {
console.info('auth.js:setAccessToken', token)
state.accessToken = token
},
setRefreshToken(state, token) {
console.info('auth.js:setRefreshToken', token)
state.refreshToken = token
},
setName(state, name) {
console.info('auth.js:setName', name)
state.user = name
},
}