5
votes

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!

1

1 Answers

4
votes

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>