# Vuex Store

Nacelle uses Vuex for state management and storing global information about your space. When writing custom components it will often be necessary to import Vuex's mapState, mapMutations, mapGetters, and mapActions helpers to access and manipulate application state.

The following store modules are included in your Nacelle project:

  • Collections - Saves collection data in order to enable saving scroll position
  • Search - Saves search queries and handles retrieving search data
  • Menu - Handles mobile menu toggle state
  • Events - Logs user events
  • User - Saves user object
  • Cart - Handles cart state and checkout processing
  • Space - Stores information about your Nacelle space

# Adding Space Data to Your Component

Let's say you have a custom component FooterMenus.vue that you would like to add to your SiteFooter.vue component. This component will display menus from your link lists and each menu will have an icon image you will set in your space's metafields. This would be an instance where you will have to use Vuex's mapGetters helper.

The Space store module has the following properties in its state:

id: ID!
linklists: [Linklist]
redirects: [Redirect]
assetStorage: String
name: String
domain: String
metafields: [metafield]

Whenever Nacelle loads or is generated it retrieves this information from your space and initializes the state. For our current example we want to use the data stored in the linklists and metafields.

Create a new file FooterMenus.vue in the /components folder. Set up a vue single-file component.

<template>
  <div class="footer-menus"></div>
</template>

<script>
  export default {}
</script>

<style></style>

Let's create a basic link to the homepage. At the top of the script section add import { mapState } from 'vuex'. Next, we will add a computed property to get the name of your space from the store.

import { mapState } from 'vuex'

export default {
  computed: {
    ...mapState('space', ['name']),
  },
}

The component will now have access to your space's name either in the script by this.name or in your templates like

{{name}}

Update your template to add the link to the homepage using the Nuxt link component.

<template>
  <div class="footer-menus">
    <nuxt-link to="/">
      {{ name }}
    </nuxt-link>
  </div>
</template>

Now we will add the navigation menu. Let's assume in your Nacelle dashboard you have added a link list with the handle "footer", and a metafield with the namespace of "icons", a key of "footer". The value will be a URL pointing to an icon image.

We can first access the linklists with a mapGetters helper and assign it to another computed property.

import { mapState, mapGetters } from 'vuex'

export default {
  computed: {
    ...mapState('space', ['name']),
    ...mapGetters('space', ['getLinks']),
    menu() {
      return this.getLinks('footer')
    },
  },
}

Now that we have retrieved the links from the link list with the handle "footer", we can loop over them in our template to build the menu.

<template>
  <div class="footer-menus">
    <nuxt-link to="/">
      {{ name }}
    </nuxt-link>
    <ul>
      <li v-for="(link, index) in menu" :key="index">
        <nuxt-link :to="link.to">
          {{ link.title }}
        </nuxt-link>
      </li>
    </ul>
  </div>
</template>

Finally lets use another getter to access your space's metafields and render the footer icon in the homepage link.

import { mapState, mapGetters } from 'vuex'

export default {
  computed: {
    ...mapState('space', ['name']),
    ...mapGetters('space', ['getLinks', 'getMetaNamespace']),
    menu() {
      return this.getLinks('footer')
    },
    icons() {
      return this.getMetaNamespace('icons')
    },
  },
}

After updating our template to display the icon image, the complete FooterMenu.vue component should look something like this:

<template>
  <div class="footer-menus">
    <nuxt-link to="/">
      <img :src="icons.footer" alt="footer icon" />
      <span>{{ name }}</span>
    </nuxt-link>
    <ul>
      <li v-for="(link, index) in menu" :key="index">
        <nuxt-link :to="link.to">
          {{ link.title }}
        </nuxt-link>
      </li>
    </ul>
  </div>
</template>

<script>
  import { mapState, mapGetters } from 'vuex'

  export default {
    computed: {
      ...mapState('space', ['name']),
      ...mapGetters('space', ['getLinks', 'getMetaNamespace']),
      menu() {
        return this.getLinks('footer')
      },
      icons() {
        return this.getMetaNamespace('icons')
      },
    },
  }
</script>

<style></style>