t2t2 / vue-syncers-feathers

Synchronises feathers services with vue objects, updated in real time
MIT License
32 stars 2 forks source link

What if i use vuex #3

Open ramstein74 opened 8 years ago

ramstein74 commented 8 years ago

Can you help how to use this package with vuex?

Regards

t2t2 commented 8 years ago

The quick and dirty way if you don't mind leaving vuex to use this:

// component.js
export default {
    store, // or in a parent component
    vuex: {
        getters: {
            currentItemId: state => state.currentItem
        }
    },
    sync: {
        currentItem: {
            service: 'items',
            id() {
                return this.currentItemId
            }
        }
    }
}
// Similar way for query

When it comes to keeping the state in vuex, there isn't a super-friendly way.

...But if you don't want to write everything completely from scratch you might be able to extend the syncers classes: (I haven't tested this but should give an idea how to)

import Vue from 'vue'
import Vuex from 'vuex'
import CollectionSyncer from 'vue-syncers-feathers/src/syncers/collection' // make sure to run this through babel, your webpack config probably will ignore node_modules

Vue.use(Vuex)

class VuexCollectionSyncer extends CollectionSyncer {
    constructor(...args) {
        super(...args)

        this.store = null
    }

    // remap _set and _remove to store.dispatches
    _set(key, item) {
        if(this.store) {
            this.store.dispatch(`FEATHERS_${this.path}_SET`, key, item)
        }
    }

    _remove(key) {
        if(this.store) {
            this.store.dispatch(`FEATHERS_${this.path}_REMOVE`, key)
        }
    }
}

const feathers = // feathers client instance

let moduleInstance = 1
function createModule(service, instance = `VUEX_${moduleInstance++}`) {
    // instance = unique key to avoid conflicts on the same store
    // arg2: need instance for throwing errors on
    const syncer = new VuexCollectionSyncer(Vue, new Vue, {feathers}, instance, {service})

    return {
        state: syncer._initialState(), // syncer.state or {} will probably work too, or [] but then write your _SET and _REMOVE methods to account for it
        mutations: {
            [`FEATHERS_${instance}_SET`] (state, key, item) {
                state[key] = item
            },
            [`FEATHERS_${instance}_REMOVE`] (state, key) {
                delete state[key]
            }
        },
        syncer
    }
}

const modules = {
    items: createModule('items')
}

const store = new Vuex.Store({
    modules
})

// Give store to syncers
Object.keys(modules).forEach(key => {
    modules[key].syncer.store = store
    // Sets up event listeners and loads the data.
    // You might want to turn this into an action to load it later when needed (see vuex shopping chart example), but watch out for calling it multiple times
    modules[key].syncer.ready()
})

export default store

(this is missing advanced stuff like specifying a query but should be a start)

ramstein74 commented 8 years ago

Too much for my level of programming. Thank you for your time anyway.

there is canjs-feathers.js and it does not need any code to have realtime data sync. Is there any reason you didnt convert it to vuejs instead of writing your own implementation of realtime sync?

Regards