Vuex ORM best practice for defining and mutating additional state

834 Views Asked by At

I wan't to extend a vuex-orm model with a state like described in the documentation: https://vuex-orm.org/guide/digging-deeper/vuex-module.html#defining-state

What ist the best way to mutate the state defined in the model? By defining a static function? I couldn't figure out how to use actions and mutations inside the model?

Here is my approach:

import { Model } from '@vuex-orm/core'

export default class Todo extends Model {
  static entity = 'todos'

  static state ()  {
    return {
      selected_id: null
    }
  }

  static fields () {
    return {
      id: this.attr(null),
      title: this.string(''),
    }
  }

  static updateSelectedTodo (selected_id) {
    Todo.commit((state) => {
      state.selected_id = selected_id
    })
  }
}

And inside a component i have a method, which triggers the static todo method like this:

methods: {
  updateSelectedTodo (selected_id) {
    Todo.updateSelectedTodo(selected_id);
  },
}

But this is no longer felt the vuex away. Or is it a better approach to define a vuex module and pass it to it, as described here: https://vuex-orm.org/guide/digging-deeper/vuex-module.html#defining-modules

But this approach would split the state and mutation definitions in a seperate file.

1

There are 1 best solutions below

0
On BEST ANSWER

Static states defined on models still require a considerable amount of verbosity beyond generic mutation, and in direct reflection of your comment "this is no longer felt the vuex way", you may be better off breaking this sort of logic into its own module to keep some form of Vuex consistency.

You don't necessarily have to put your module in a separate file, this is a matter of opinion. You can declare and export your module in the same file:

export default class Todo extends Model {
  static entity = 'todos'

  static fields () { ... }
}

export const todos = {
  state: {
    selected_id: null
  },
  mutations: {
    updateSelected: (state, selected_id) => {
      state.selected_id = selected_id
    }
  },
  getters: {
    selected: (state) => state.selected_id
  }
}

And import it when registering to the store:

import Todo, { todos } from '...'

database.register(Todo, todos)

Regardless, you will still need to invoke these mutations as you would generally with Vuex modules, with the exception you'll be invoking directly on the related model:

export default {
  computed: {
    selectedTodo: {
      get: () => Todo.getters('selected'),
      set: (selected_id) => Todo.commit('updateSelected', selected_id)
    }
  }
}