I make use of the new Vue 3 Composition API and have written a "store" for reactive data.
const state = reactive<State>({
accessToken: undefined,
user: undefined,
});
export default {
state: readonly(state),
}
On App creation I provide the store to all components:
const app = createApp(App)
.provide("store", store)
.use(IonicVue)
.use(router);
And finally in a component / view I inject the store to make use of it.
export default defineComponent({
name: "Home",
inject: ["store"],
components: {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
IonButton,
},
computed: {
email() {
return this.store.state.user.email;
},
},
});
</script>
Unfortunately Typescript doesn't like the way I use this.store
in the computed property email()
And says
Property 'store' does not exist on type 'ComponentPublicInstance<{}, {}, {}, { email(): any; }, {}, EmitsOptions, {}, {}, false, ComponentOptionsBase<{}, {}, {}, { email(): any; }, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, {}>>'
I mean everything works fine when I remove the lang="ts"
in the <script/>
tag, but without the error is displayed.
Any suggestions on how to fix this or what it particularly means?
Thanks in advance!
I recommend to use the store as a global property without specifying the inject
in any child component because provide/inject could have some reactivity caveats:
const app = createApp(App)
.use(IonicVue)
.use(router);
app.config.globalProperties.store= store;
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
store:any // replace it with the right type
}
}
then use it directly :
export default defineComponent({
name: "Home",
components: {
...
},
computed: {
email() {
return this.store.state.user.email;
},
},
});
</script>
For those who are dealing with the same issue with Vue 3 + TS, I found a solution without having to change the app.config
or declare a new module
:
import { createApp, reactive } from 'vue'
import App from './App.vue'
const Store = reactive({
myProperty: 'my value'
})
createApp(App)
.provide('Store', Store)
.mount('#app')
<template>
<div>{{ Store.myProperty }}</div>
</template>
<script lang="ts">
import { IStore } from '@/types'
import { defineComponent, inject } from 'vue'
export default defineComponent({
name: 'MyComponentName',
setup() {
return {
Store: inject('Store') as IStore,
}
},
created() {
console.log(this.Store) // will show the `Store` in the console
}
})
</script>
@/types.ts
):export interface IStore {
myProperty: string
}
Following these 3 steps I was able to read/write to Store.myProperty
without problems using TypeScript
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With