I am working on a Vue plugin for Pouch/CouchDB which will be open sourced, but as long as i can figure out an issue i am having:
Currently i am trying to make the plugin closely to resemble Vuex, that has an internal state, and detect changes, and render the view when they happen.
Inside the Vue instance i am initializing an object, and within that object i am trying to make two or three objects reactive, with defineReactive, until here its good.
But when i try to change some values inside that object, the changes are not propagated to the View. BUT if i explicitly call this.$bucket._state.projects.__ob__.dep.notify(), the changes propagate.
The current object representation of the Vue instance is like this: Vue { $bucket: { _state: { projects: {} } } }
$bucket._state has been initialized with defineReactive. which i believe it should work, but i am not sure what's the exact problem in this case.
Any idea?
A partial of the code, the class in here is almost similar to Vuex.Store({})
    constructor(schema = {}) {
    // Getting defineReactive from Vue
    const { defineReactive } = Vue.util;
    // Ignored Schema Keys
    const ignoredKeys = [
      'config',
      'plugins'
    ];
    // Internal Variables
    this._dbs = {};
    // Define Reactive Objects
    defineReactive(this, '_state', {});
    defineReactive(this, '_views', {});
    // Local Variables
    if (!schema.config) {
      throw new Error(`[Pouch Bucket]: Config is not declared in the upper level!`);
    }
    // Init PouchDB plugins
    if ((schema.plugins.constructor === Array) && (schema.plugins.length > 0)) {
      for (let i = 0; i < schema.plugins.length; i++) {
        PouchDB.plugin(
          schema.plugins[i]
        );
      }
    }
    // Initializing DBs that are declared in the schema{}
    for (const dbname in schema) {
      if (schema.hasOwnProperty(dbname) && ignoredKeys.indexOf(dbname) === -1) {
        this._initDB(
          dbname,
          Object.assign(
            schema.config,
            schema[dbname].config ? schema[dbname].config : {}
          )
        );
        this._initState(dbname);
      }
    }
  }
                I think you don't need to use these internal APIs like Vue.util.defineReactive or this.$bucket._state.projects.__ob__.dep.notify()
Because Vue itself is reactive, you can use a Vue instance to store the data. There is no need to reinvent the reactivity system.
Create a Vue instance in the constructor:
this.storeVM = new Vue({ data })
and use getter to delegate the .state to storeVM.$data
get state () {
  return this.storeVM.$data
}
so when you access myPlugin.state, you are accessing the data of the Vue instance.
I created a very simple reactive plugin example: http://codepen.io/CodinCat/pen/GrmLmG?editors=1010
No need to use defineReactive or notify the dependencies by yourself if a Vue instance can do everything for you. In fact, this is how Vuex works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With