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
-
Less code. No need to create
setInitialState
actions (and associated mutations/types/specs) like this. -
Simplicity. Currently, during app initialization, data flows through our application like this:
- Rails renders data into the HTML page as
data-*
attributes - The Vue app initialization script plucks these values from the page and passes them as props to the root Vue component
- The root Vue component calls
setInitialState
duringcreated
ormounted
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. - Rails renders data into the HTML page as
-
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
- 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"
- Because initial data is not passed through Vue
props
, we loseprops
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:
- 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'screated
ormounted
hook like this. - This store is used as a module. Most Vuex applications in our existing codebase do not make use of modules.