This library tries to emulate an orm-style data structure in your vue application. It works by defining Models whose attributes are reactive and can directly be used in templates.
Install package
npm install vue-model
Define Model
import { Model } from 'vue-model'
class User extends Model {
// Name of the Model
static model = 'User'
// Define fields and relations
static fields () {
return {
id: this.uid(),
count: this.number(0),
name: this.string(generateRandomName),
isAdmin: this.boolean(false),
session: this.belongsTo(Session),
sessionId: this.string(null),
lastLogins: this.array([], Date),
someObject: this.field({foo: 'bar'}, Object)
}
}
}
class Session extends Model {
// Name of the Model
static model = 'Session'
// Define fields and relations
static fields () {
return {
id: this.uid(),
user: this.hasOne(User),
loggedIn: this.boolean(false)
}
}
}
Use Model
const user = User.create()
// same as new User().save()
User.get(user.id) === user // true
user.session // null
user.session = {} // creates new session out of {}
user.session // Session
Every type takes a default value or a function generating a default value. Whatever type the default value is, it will be castet to the specified typ. The exception is uid
which does not take a default value. When null
is passed, the field is automatically set as nullable.
class Dummy extends Model {
static model = 'Dummy'
static fields () {
return {
// uuid
id: this.uuid()
// number
number: this.number(0).nullable() // default 0 but also nullable
// string
string: this.string('Hello World')
// boolean
boolean: this.boolean(true)
// array of numbers
array: this.array([1,2,3], Number)
// any other type with default value and constructor function
field: this.field(Date.now, Date)
}
}
}
vue-model supports all common relations. Relations are resolved on the fly and updated through an internal messaging system. That means that this implementation does not suffer from filtering big arrays of maybe-children whenever a child model is created and stays blazingly fast (not as other implementations such as VuexORM).
class Dummy2 extends Model {
static model = 'Dummy2'
static primaryKey = 'id' // this is the default
static fields () {
return {
// hasOne
child: this.hasOne(ChildModel, foreignKey, localKey)
// only Model parameter is required:
child: this.hasOne(ChildModel) // foreignKey = 'childModelId', localKey = primaryKey = 'id'
// string also works
child: this.hasOne('ChildModel')
// belongsTo
parent: this.belongsTo(ParentModel, foreignKey /* = parentModelId */, localKey)
parentId: this.string(null)
// hasMany
children: this.hasMany(ChildModel)
// hasManyBy
children: this.hasManyBy(ChildModel)
childModelId: this.array([], String)
// belongsToMany
opinions: this.belongsToMany(Opinion, PivotModel, foreignKey1 /* = dummy2Id */, foreignKey2 /* = opinionId */, localId1, localId2)
}
}
}
Usually you only need to specify the related model and vue-model will figure out the ids by itself. However, if you want to deviate from the standard you can do so and specify the ids.
If you want to delete related models if a model is deleted, specify the models to delete in the cascade method:
class Dummy3 extends Model {
static cascade () {
return [ 'nameOfRelation' ]
}
}
There are several ways to create a new model
// Creates an instance but doesnt save it in the registry
// That means it wont appear in other models as relation
const dummy = new Dummy(values)
const dummy = Dummy.make(values)
// To save it, call save which will notify related models
dummy.save()
// Shortcut
const dummy = Dummy.create(values)
// Multiple at once
const dummy = Dummy.create([values, values])
And a few more to get a model
const dummy = Dummy.get(id)
const dummies = Dummy.get(ids)
const dummies = Dummy.all()
const dummy = Dummy.whereFirst({...conditions})
const dummy = Dummy.whereFirst(checkerFunction)
const dummies = Dummy.where(conditionOrFunction)
Sometimes you conditionally want to get or create a model
// Looks for the primary key in values and gets the model if it exists, otherwise creates it
const dummy = Dummy.getOrCreate({values})
// Updates an existing model or creates a new one out of values
const dummy = Dummy.fillOrCreate({values})
const dummy = Dummy.create(values)
// Removes model from registry
dummy.delete()
// Fills model with values and reinitizes missing ones with default values
dummy.fill(values)
// Gives back an unsaved copy of the same model
// Only one instance of the same model can ever exist in the registry.
// Saving this will NOT replace the old model but just update it
dummy.clone()
// Gives back an unsaved copy with new id
dummy.copy()
// Gives back a plain object without relations
dummy.toObject()
// Gives back a plain object with added __class__ field which can be rehydrated
dummy.dehydrate()
// Creates or gets a model of the right type from values (and the property __class__ with the name of the model)
Model.hydrate(values)
// Adds/removes a callback to a model event
dummy.on('event', cb)
dummy.off('event', cb)
// Emits a model event
dummy.emit('event', data)