Andy from Webcrunch

Subscribe for email updates:

Portrait of Andy Leverenz
Andy Leverenz

November 14, 2020

Last updated November 5, 2023

Let's build for Ruby and Rails developers - Part 13

Enhancing state of the Vue.js app

In part 13 I take a step back at our very rough Vue.js application to start to consider state management. There are a few routes we could take when it comes to using a store pattern using Vue.js but the most simple pattern I prefer is the Vue.observable pattern.

If you're new to Vue.js this might be a bit complex but the idea is to mimic the saved state as you navigate a Vue application. This can get tedious as you add more and more components. Having a center "store" (kind of like a database) is a good pattern to adopt as your app scales.

A popular extension to Vue.js is called Vuex which is like the "store" pattern on steroids. That library comes with its conventions and learning curves so I didn't want to go that deep for our purposes.

How does the observable pattern work in Vue.js?

The observable pattern lets you have a central store which is a fancy way of saying a stateful object that you can update or change on the fly. A good practice is to also introduce center "actions" that are responsible for changing the store.

Here's a quick demo of that concept.

import Vue from "vue/dist/vue.esm"
import MyApp from "./components/MyApp.vue"

const store = Vue.observable({
  name: null,
  email: null,

const actions = {
  someFunction() {
    // logic

  anotherFunction() {
    // logic

Vue.prototype.$store = store
Vue.prototype.$actions = actions

const app = new Vue({
  el: "#myApp",
  render: (h) => h(MyApp),
  data: store,

First, we import Vue and our main application as a component. At the very bottom of the code block, I initialize the Vue app. I pass the element to mount the app to, render the main app component, and pass a variable called store to the data attribute.

If you take a look at the code in between the imports and the initialization of the Vue app you'll find both a store and actions variable. The store variable is unique in that it is essentially an object but on that hooks into Vue.observable that in return makes the object reactive. We'll use this as a "source of truth" during this phase for the Vue app.

The actions variable (also an object) represents the actions or methods you might need to use to update the now reactive store object. These can live outside of the bonds of individual Vue components. This approach does a few things to benefit our flow:

  1. Makes our lives easier when manipulating the state
  2. Components become less complex
  3. Moves most of the business logic to the main app initializer which is easier to maintain.

The most important two lines to remember when using the observable pattern and actions pattern is to notify Vue of them.

Vue.prototype.$store = store
Vue.prototype.$actions = actions

The lines above hook into the Vue prototype pattern and pass in our new objects. With this set, we can now access our store or actions from anywhere in our app using $store and $actions.


The second half of part 13 is spent introducing localStorage to our new job form. I chose this approach for a few reasons.

  1. I don't want to save data that might get abandoned
  2. localStorage is quite easy to use and manipulate
  3. Using localStorage improves user experience by a shit ton should you navigate away from the form for some reason.

On the surface how I use localStorage to update our state is a little complex but we break it down into a duplicated object that mimics the store we created earlier. As you enter data in each field of the new job form we can fire an event to update the localStorage data accordingly. This means even if you navigated away from the page your progress would be saved. In a future part, I'll need to build a new mechanism to reset the form and delete that saved localStorage data. It should be relatively straight forward!

Closing up

This is probably the longest part of the series so far. I apologize if it's dull to watch or there are some unedited bits. I'm trying to make the best use of my time where I can to slowly bring this idea to life. I hope you'll understand. See you in part 14!

Link this article
Est. reading time: 4 minutes
Stats: 1,224 views



Part of the Let's Build for Ruby and Rails Developers collection