1.0.2 • Published 7 years ago
vuejs-data-plugin v1.0.2
vuejs-data-plugin
vuejs >= 2 to js-data >= 3 mapper plugin.
Table of contents
New Project quick start
Quick test Install
npm i -g vue-cli
vue init webpack-simple myNewProjet
npm install --save-dev js-data#rc js-data-localstorage#rc vuejs-data-plugin
Store definition
define a store with an adapter. The Localstorage adapter in this case.
import { DataStore } from 'js-data'
import { LocalStorageAdapter } from 'js-data-localstorage'
const DS = new DataStore()
DS.registerAdapter('ls', new LocalStorageAdapter(), {'default': true})
resource definition
DS.defineMapper('tasks', {
beforeCreate(props, opts) {
props['created_at'] = new Date()
return props
},
schema: {
type: 'object',
track: true,
properties: {
name: {},
done: {},
created_at: {}
}
}
})
Side note on track & properties.
this option is important as in js-data@3 the change
event is only triggered on tracked properties.
So in short you have to name the properties you're expecting and set the track property to true. (globally like above or per prop like below)
DS.defineMapper('tasks', {
schema: {
properties: {
name: {
tracked: true
},
done: {
tracked: true
},
created_at: {}
}
}
})
Vue instantiation
import Vue from 'vue'
import App from './App.vue'
import DS from './DS'
import jsDataPlugin from 'vuejs-data-plugin'
Vue.use(jsDataPlugin)
const vm = new Vue({
el: '#app',
template: '<App/>',
components: {App},
DS
})
vm.$DS === DS
this will expose the DataStore as $DS
but fill free to rename it however you want. the plugin will look for the name you setted at injection.
const vm = new Vue({
myFunkyStore: DS
})
vm.$myFunkyStore === DS
So this is fine too.
In components usage
<template>
<input type="text" @keyup.enter"newTask" v-model="name">
<ul>
<li v-for="task in tasks" :key="task.id">
<label><input type="checkbox" v-model="task.done"></label>
<label><input type="text" v-model="task.name" :disabled="task.done"></label>
<button @click="task.destroy()">delete</button>
<span v-if="task.hasChanges()">
<button @click="task.save()">save</button>
<button @click="task.revert()">revert</button>
</span>
</li>
</ul>
</template>
<script>
import {
mapResources
} from 'vuejs-data-plugin'
export default {
name: 'task',
computed: {
// fetch a previously defined resource
...mapResources({
taskRepo: 'tasks',
}),
// set a computed prop to map a collection (cache false is important)
tasks: {
cache: false,
get () {
return this.taskRepo.filter({
sort: 'created_at'
})
}
}
},
methods: {
newTask () {
this.taskRepo.create({
name: this.name,
done: false
}).then(() => {
this.name = ''
})
}
},
created () {
//fetch the remote resource on vue created hook
this.taskRepo.findAll()
// auto save on done prop change
this.taskRepo.on('change', (res, record, change) => {
if (change.changed.done !== undefined) record.save()
})
},
data: () => ({
name: ''
})
}
</script>
side note on mapResources
It work much like vuex mapGetters
. You can declare the binding in 3 different ways.
- object format to specify a different name
...mapResources({ taskRepo: 'tasks', userRepo: 'users', })
- array format for multiple
...mapResources([ 'tasks', 'users' ])
- string format for single
...mapResources('tasks')
Bug
Fill free to open an issue there if you find anythings.
License
license (MIT)