53. Introduction to Vuex ORM


Resources:


We're going to be using a Vuex store for the PrintBay client, as it's a powerful way to manage our application state across different views.

But, remember that we're following enterprise principles for developing our app, so we want to ensure that the code is as scalable and maintainable as possible.

For this reason, we're going to be using Vuex ORM, which is a plugin for Vuex, that allows us to think of our application state as models, rather than formless data.

Another advantage of Vuex ORM is that it allows us to not worry so much about the inner workings and boilerplate of Vuex when working with our app state.

Instead, we can use the simple interface of our Vuex ORM models. For example, in pure Vuex you might have a statement in your component code like store.state.commit("UPDATE_USER"). Using a Vuex ORM model abstraction, we can use much simpler syntax like User.update(), which is designed to do the same thing.

Installation

So hopefully I've intrigued you about Vuex ORM. Let's go ahead now and install it by typing:

$ npm i @vuex-orm/core -D

Item model

Similar to Mongoose, Vuex ORM abstracts data into models.

Obviously, we'll use the the same entities in our client app as we did in our backend app - that is, items and users.

So let's now create a directory for our models, by going:

$ mkdir client/store/models

We'll then create our item model file:

$ touch client/store/models/Item.js

Item schema

Let's now define the schema for our item model.

One interesting thing about Vuex ORM models, is that they're defined with classes, unlike Vue and most other Vue plugins which are normally defined with objects.

So let's import the Model class from the Vuex ORM core library by going import { Model } from "@vuex-orm/core";

After that, we can now extend the Model class and create our new class. So we'll go export default class Item extends Model {}.

The first thing we'll add to our item schema is a static property entity. This property is used to name the model, and should be the plural of the entity name, which, in this case, is items with an "s". You'll see why this is important later on.

client/store/models/Item.js

import { Model } from "@vuex-orm/core";

export default class Item extends Model {
  static entity = "items";
}

Fields

Next, let's define the fields of our model, by creating a static method, fields. This method will return an object containing the field definitions.

Rather than going through each field individually, I'm just going to paste them in.

If you've built the backend API, these fields name will all be familiar to you, as they reflect the properties of our backend item model.

Vuex ORM allows you to specify the type of field, so we've got strings for id, title, artist and image, and a number for year and price. Finally, the value you pass is simply the default value for that field.

client/store/models/Item.js

static fields () {
  return {
    id: this.string(""),
    title: this.string(""),
    artist: this.string(""),
    image: this.string(""),
    year: this.number(0),
    price: this.number(0)
  };
}

Module

The way that Vuex ORM works under the hood is by turning this model schema into a Vuex module with a series of mutations and getters. It then installs all that in the Vuex store.

As you'll see in a moment, each Vuex ORM model provides all the standard CRUD operations like create, update, and so on. These methods are aliases of more complex Vuex mutations and getters that have been encapsulated by the model.

My point is that in addition to defining the schema for the model, we also can define our own pure Vuex methods for this model with the module file.

The reason we may want to do this is to extend the features of the model, very similar to how we extended the features of our Mongoose models.

So let's go ahead and create a new directory for our modules, by going:

$ mkdir client/store/modules

Now we can create an item module file:

$ touch client/store/modules/item.js

For now, we don't actually have any custom methods for this module, so we're going to simply export an empty object from this file. We'll come back and add some stuff in here later.

client/store/modules/item.js

export default {};

Store

Over in the store file, we have the default store code from the Vue CLI 3 installation.

Let's begin by clearing every everything out of this file. We'll then go ahead and import VuexORM, and the Item model and module, by going:

client/store/index.js

import VuexORM from "@vuex-orm/core";
import Item from "@/store/models/Item";
import item from "@/store/modules/item";

Database

In order to use our model and install it in the underlying Vuex store, we have to create an instance of the Vuex ORM database. So let's do that by going const database = new VuexORM.Database();

We can then register our model in the database by calling the register method of the database and passing in the model file as the first argument and the module file as the second argument.

Finally, we install the database in the Vuex ORM instance by going VuexORM.install(database);

client/store/index.js

...

const database = new VuexORM.Database();
database.register(Item, item);

VuexORM.install(database);

...
`

With that done, our item model is now registered and ready to use in our components.

Installation in store

And finally, remember that Vuex ORM is a Vuex plugin, and as such, needs to be installed itself. Let's create a variable VuexORMPlugin and assign to it VuexORM.install(database).

We can then export an object to represent our store config and add a plugins property to this. We can assign an array to that and pass in VuexORMPlugin.

client/store/index.js

const VuexORMPlugin = VuexORM.install(database);

export default {
  plugins: [VuexORMPlugin]
};
`

Dev server

That's all we need to do for our VuexORM installation.

Let's now serve our app with the dev server. You'll recall from module 1 of this course that we can run both our front and backend servers with the command:

$ npm run serve

Vue Devtools

With our site now being served, let's go to the browser and open our site. We'll open Vue Devtools and look in the Vuex tab and inspect our store.

Now that Vuex ORM is installed, you'll see now in the state that we have a property entities. This is where the state of our Vuex ORM models gets stored.

Inside that, you can see our items model has been included. If we inspect that, we can see the data, which is currently empty as we haven't created any instances of the items model yet.

Down in the getters section we can see some more interesting stuff. All these getters are the model methods that we can use. For example, you'll see there is a getter "entities/items/find", which is used to query our items.

We'll get much more familiar with those in the coming videos.

Discussion

1 comments