DEV Community

Cover image for Small Store with Vue.observable
Davidson Ratis
Davidson Ratis

Posted on • Updated on

Small Store with Vue.observable

In large and medium sized projects we usually use Vuex. But what to use in small projects? Would it be necessary to install a new dependencie in such a simple project?

Vue.observable (included in Vue v2.6.0) can be a lightweight alternative to state management in smaller applications. It was thinking about it that I tried to create a solution to access this state and manipulate it in a simple way. Similar to Vuex, in this store the functions that return the value of a property that is in the state are in getters and the manipulators in mutations.

Note: When there is a need to use "actions", use Vuex.

createStore.js

import Vue from 'vue'

const err01 = 'does not exist'
const err02 = 'is not function'
const err03 = 'function returning undefined'

function showErr(msg){
  const err = new Error(msg)
  console.error(err.message)
}

function createStore({ state, getters, mutations }){
  const myGetters = {}

  if(getters){
    Object.entries(getters).forEach(([key, value])=> {
      Object.defineProperty(myGetters, key, {
        get: () => {
          return typeof value !== 'function' ? 
          showErr(`${key} ${err02} (getters)`) :
          value(state) === undefined ? 
          showErr(`${key} ${err03} (getters)`) : 
          value(state)
        }
      })
    })
  }

  return {
    state: Vue.observable(state),
    getters: myGetters,
    commit(key, ...args){
      const cb = key => key == key
      !Object.keys(mutations).some(cb) ? 
      showErr(`function ${key} ${err01} (mutations)`) :
      typeof mutations[key] !== 'function' ? 
      showErr(`${key} ${err02} (mutations)`) :
      mutations[key](state, ...args)
    }
  }
}

export default createStore
Enter fullscreen mode Exit fullscreen mode

store.js (importing the createStore function)

import createStore from './createStore.js'

const store = createStore({
    state: {
      tasks: []
    },
    getters: {
      tasks(state){
        return state.tasks
      }
    },
    mutations: {
      addTask(state, payload){
        state.tasks.push(payload)
      }
    },
})

export default store
Enter fullscreen mode Exit fullscreen mode

Use methods in a component

<script>
import store from "@/store";

export default {
  computed: {
    tasks() {
      return store.getters.tasks;
    },
  },
  methods: {
    addTask() {
      store.commit("addTask", this.task);
    },
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

I know that there are some articles that deal with the subject, but I didn't like the way the problem was solved. So I decided to create my solution. This is my first article, I hope you like it. I thank everyone who read it.

Here is a demo about small store: https://github.com/davR7/small-store

Discussion (0)