Skip to content

New: Populate Vuex store's initial state when creating store

New Pattern Proposal

Initialize Vuex store state by passing it to the store's creation function.

This pattern will be familiar to those who have used Redux.

tl;dr:

// in the Vue app's initialization script

import Vue from 'vue';
import createStore from './stores';
import AwesomeVueApp from './components/awesome_vue_app.vue'

export default () => {

  // initial state is stored in the element's data-* attributes
  const el = document.getElementById('js-awesome-vue-app');

  return new Vue({
    el,

    // initialize the store with the data from Rails
    store: createStore(el.dataset),

    render: h => h(AwesomeVueApp)
  });
};

Advantages of new pattern

  1. Less code. No need to create setInitialState actions (and associated mutations/types/specs) like this.

  2. Simplicity. Currently, during app initialization, data flows through our application like this:

    1. Rails renders data into the HTML page as data-* attributes
    2. The Vue app initialization script plucks these values from the page and passes them as props to the root Vue component
    3. The root Vue component calls setInitialState during created or mounted to pass this data to the store


    Passing initial state directly to the store allows us to skip step #3 and avoids involving components in this plumbing.

  3. Consistency (relative to our current state, which is no pattern). Going forward, all Vuex stores would be initialized in the same way.

Disadvantages of new pattern

  1. No mutation record for the setting of the initial state. For example, no SET_INITIAL_STATE mutation will be shown in the Vuex dev tools
    • However, the value of the initial state is still available in the Veux dev tools by clicking "Base State"
  2. Because initial data is not passed through Vue props, we lose props validation such as types and existence

What is the impact on our existing codebase?

None. This would only be a guideline for new code.

Reference implementation

This reference implementation shows a conversion of a Vuex store from the setInitialState method mentioned above to the new pattern proposed by this RFC.

There are a couple of things that are unique to this implementation that may not apply to most Vuex stores in our codebase:

  1. Previously, setInitialState was manually dispatched from the Vue app's initialization script. This is a bit unusual; the most common pattern in our codebase is call this action from a component's created or mounted hook like this.
  2. This store is used as a module. Most Vuex applications in our existing codebase do not make use of modules.
Edited by Nathan Friend