useStore() method always leading to undefined value within components

Viewed 2841

I am using Vue3/Vuex 4/TypeScript.

I am trying to access my typed store from within my component (App.vue).

Whenever I set const store = useStore(), store will always return as undefined

As far as I can tell, I've followed the official Vuex 4 TypeScript Support Documentation verbatim.

app.ts

import { createApp, Component } from "vue"
import { createWebHistory, createRouter } from "vue-router"
import { store, key } from "./store/store"
import App from "./pages/App.vue"
import Home from "./pages/Home.vue"
import Lookup from "./pages/Lookup.vue"

const About = { template: "<div>About</div>" }

const routes = [
  { path: "/", name: "home", component: Home as Component },
  { path: "/about", name: "about", component: About },
  { path: "/lookup", name: "lookup", component: Lookup as Component },
]

const router = createRouter({
  history: createWebHistory(),
  routes,
})

createApp(App).use(router, store, key).mount("#app")

export default router

store.ts

import { InjectionKey } from 'vue'
import { createStore, useStore as baseUseStore, Store } from 'vuex'

export interface State {
  count: number
}

export const key: InjectionKey<Store<State>> = Symbol()

export const store = createStore<State>({
  state: {
    count: 0
  }
})

// define your own `useStore` composition function
export function useStore () {
  return baseUseStore(key)
}

App.vue

<script lang="ts">
import { useStore } from '../store/store'
export default {
  setup(): { [key: string]: unknown } {
    const foo = "bar"

    const store = useStore()
    
    console.log(store)
    console.log(store.state.count)

    return { foo }
  },
}
</script>

store is always returning as undefined, here's my console messages from FireFox

[Vue warn]: injection "Symbol()" not found. 
  at <App> app.js:5871:17
undefined app.js:16779:13
[Vue warn]: Unhandled error during execution of setup function 
  at <App> app.js:5871:17
Uncaught TypeError: store is undefined
    setup http://boilerplate.local/js/app.js:16780
    callWithErrorHandling http://boilerplate.local/js/app.js:5987
    setupStatefulComponent http://boilerplate.local/js/app.js:12359
    setupComponent http://boilerplate.local/js/app.js:12320
    mountComponent http://boilerplate.local/js/app.js:10027
    processComponent http://boilerplate.local/js/app.js:10003
    patch http://boilerplate.local/js/app.js:9621
    render http://boilerplate.local/js/app.js:10704
    mount http://boilerplate.local/js/app.js:8907
    mount http://boilerplate.local/js/app.js:14290
    <anonymous> http://boilerplate.local/js/app.js:23012
    <anonymous> http://boilerplate.local/js/app.js:23014
    <anonymous> http://boilerplate.local/js/app.js:23016

I've tried to debug this all day but really can't narrow in on the problem. Any help/guidance is greatly appreciated.

1 Answers

Your syntax for installing the Vuex instance to your app is a little off. You can only install one Vue plugin to an app in each call to use, so combining router, store, key like that doesn't work. As such, Vuex isn't getting installed at all.

To fix, change this line:

createApp(App).use(router, store, key).mount("#app")

to this:

createApp(App).use(router).use(store, key).mount("#app")

(key is just an option passed to store, so it does belong in the second call.)

Related