Théo Lavaux
Théo Lavaux

Reputation: 1454

Nuxt read module state inside a component

I've got a Nuxt application with a store directory that resembles this folder https://nuxtjs.org/docs/2.x/directory-structure/store#example-folder-structure.

Imagine that I have a property isComplete in my module state inside the cart folder.

I get the following error that Property 'shop' does not exist on type 'RootState'.

How could I access this property in a Vue component ?

Component.vue

<script lang="ts">
import { defineComponent, onMounted } from '@nuxtjs/composition-api'
import { useStore } from '~/store'

export default defineComponent({
  name: 'Component',
  setup() {
    const store = useStore()

    onMounted(() => {
      if (store.state.shop.cart.isComplete) {
        // Execute some code
      }
    })
  },
})
</script>

My store/index.ts has the following implementation

import { InjectionKey, useStore as baseUseStore } from '@nuxtjs/composition-api'

export interface RootState {}

export const state = () => ({})

export const injectionKey: InjectionKey<RootState> =
  Symbol('vuex-injection-key')

export const useStore = () => {
  return baseUseStore(injectionKey)
}

store/shop/cart/state.ts

export interface CartState {
  isComplete: boolean
}

export const state = (): CartState => ({
  isComplete: false,
})

Upvotes: 0

Views: 717

Answers (1)

tony19
tony19

Reputation: 138276

Store state

Store files named state should have an object-returning method as its default export, so store/shop/cart/state.ts should contain export default state (where state is the method) as its last line. Otherwise, you'll see a warning in the browser console:

store/shop/cart/state.ts should export a method that returns an object

Or you could rename store/shop/cart/state.ts to store/shop/cart/index.ts (perhaps the original intent based on the exported state constant).

RootState type

There's no type inference available here, so the RootState needs to be explicitly typed to include the states of modules.

  1. Import the CartState from the namespaced module.

  2. Add a key named after each namespaced module, nested as needed (i.e., shop and then cart). Apply the CartState type for the cart key.

// store/index.ts
import type { CartState } from './shop/cart' 1️⃣

export interface RootState {
  shop: {
    cart: CartState, 2️⃣
  }
}

GitHub demo

Upvotes: 2

Related Questions