Vuex ORM is a plugin for Vuex to enable Object-Relational Mapping access to the Vuex Store. Vuex ORM lets you create "normalized" data schema within Vuex Store with relationships such as "Has One" and "Belongs To Many" like any other usual ORM library. It also provides fluent API to get, search and update Store state.
Vuex ORM is heavily inspired by Redux recipe of "Normalizing State Shape" and "Updating Normalized Data". Learn more about the concept and motivation of Vuex ORM at What is Vuex ORM?.
Vuex ORM is sponsored by awesome folks. Big love to all of them from whole Vuex ORM community 💕
You can check out the full documentation for Vuex ORM at https://vuex-orm.github.io/vuex-orm.
Join us on our Slack Channel for any questions and discussions.
Although there is the Slack Channel, do not hesitate to open an issue for any question you might have. We're always more than happy to hear any feedback, and we don't care what kind of form they are.
You can find example applications built using Vuex ORM at;
- Vuex ORM Examples – Simple ToDo App built on top of a plain Vue structure generated by Vue CLI.
- Vuex ORM Examples Nuxt – Simple ToDo App built on top of Nuxt.js.
Here's a very simple quick start guide that demonstrates how it feels like to be using Vuex ORM.
Install Vuex ORM with npm or yarn.
$ npm install @vuex-orm/core
# OR
$ yarn add @vuex-orm/core
First, let's declare our models extending Vuex ORM Model
. Here we assume that there are Post model and User model. Post model has a relationship with User – the post "belongs to" a user by the author
key.
// User Model
import { Model } from '@vuex-orm/core'
export default class User extends Model {
// This is the name used as module name of the Vuex Store.
static entity = 'users'
// List of all fields (schema) of the post model. `this.attr` is used
// for the generic field type. The argument is the default value.
static fields () {
return {
id: this.attr(null),
name: this.attr(''),
email: this.attr('')
}
}
}
// Post Model
import { Model } from '@vuex-orm/core'
import User from './User'
export default class Post extends Model {
static entity = 'posts'
// `this.belongsTo` is for the belongs to relationship.
static fields () {
return {
id: this.attr(null),
user_id: this.attr(null),
title: this.attr(''),
body: this.attr(''),
published: this.attr(false),
author: this.belongsTo(User, 'user_id')
}
}
}
With the above example, we can see that the author
field at Post
model has a relation of belongsTo
with User
model.
Next, it's time to register the models to Vuex. To do so, we first have to register the models to the database and then register the database to Vuex Store as a Vuex plugin using Vuex ORM's install
method.
import Vue from 'vue'
import Vuex from 'vuex'
import VuexORM from '@vuex-orm/core'
import User from './User'
import Post from './Post'
Vue.use(Vuex)
// Create a new database instance.
const database = new VuexORM.Database()
// Register Models to the database.
database.register(User)
database.register(Post)
// Create Vuex Store and register database through Vuex ORM.
const store = new Vuex.Store({
plugins: [VuexORM.install(database)]
})
export default store
Now we are ready to go. Vuex ORM is going to create entities
module in Vuex Store. This means there will be a store.state.entities
state within the store.
We can use Model's insert
method, or dispatch a Vuex action to create new records in Vuex Store. Let's say we want to save a single post data to the store.
// Assuming this data structure is the response from the API backend.
const posts = [
{
id: 1,
title: 'Hello, world!',
body: 'Some awesome body text...',
author: {
id: 1,
name: 'John Doe',
email: 'john@example.com'
}
}
]
Post.insert({ data: posts })
// Or...
store.dispatch('entities/posts/insert', { data: posts })
By executing the insert
method, Vuex ORM creates the following schema in Vuex Store.
// Inside `store.state.entities`.
{
posts: {
data: {
'1': {
id: 1,
user_id: 1,
title: 'Hello, world!',
body: 'Some awesome body...',
author: null
}
}
},
users: {
data: {
'1': {
id: 1,
name: 'John Doe',
email: 'john@example.com'
}
}
}
}
See how posts
and users
are decoupled from each other. This is what is meant by "normalizing" the data.
Vuex ORM provides a way to query and fetch data in an organized way through Model methods or Vuex Getters.
// Fetch all post records.
Post.all()
// Or...
store.getters['entities/posts/all']()
/*
[
{
id: 1,
user_id: 1,
title: 'Hello,
world!',
body: 'Some awesome body...',
author: null
},
...
]
*/
// Fetch single record with relation.
Post.query().with('author').first()
// Or...
store.getters['entities/posts/query']().with('author').first()
/*
{
id: 1,
user_id: 1,
title: 'Hello, world!',
body: 'Some awesome body...',
author: {
id: 1,
name: 'John Doe',
email: 'john@example.com'
}
}
*/
Cool right? To get to know more about Vuex ORM, please see the documentation
Vuex ORM can be extended via plugins to add additional features. Here is a list of available plugins.
- Vuex ORM Axios – The plugin to sync the store against a RESTful API.
- Vuex ORM GraphQL – The plugin to sync the store against a GraphQL API.
- Vuex ORM Search – The plugin adds a search() method to filter records using fuzzy search logic from the Fuse.js.
- Vuex ORM Change Flags - Vuex ORM plugin for adding IsDirty / IsNew flags to model entities.
- Vuex ORM Soft Delete – Vuex ORM plugin for adding soft delete feature to model entities.
You can find a list of awesome things related to Vuex ORM at Awesome Vuex ORM.
We are excited that you are interested in contributing to Vuex ORM! Anything from raising an issue, submitting an idea of a new feature, or making a pull request is welcome!
$ npm run build
Compile files and generate bundles in dist
directory.
$ npm run lint
Lint files using a rule of Standard JS.
$ npm run test
Run the test using Jest.
$ npm run test:watch
Run the test in watch mode.
$ npm run test:perf
Run the performance test.
$ npm run coverage
Generate test coverage in coverage
directory.
The Vuex ORM is open-sourced software licensed under the MIT license.