VueJS Reactive Binding for a plugin - how?

I am working on a Vue plugin for Pouch / CouchDB that will be open source, but as long as I can figure out what I have:

I'm currently trying to make the plugin closely look like Vuex, which has an internal state, and detects changes and renders the view when they happen.

Inside the Vue instance, I initialize the object, and inside this object I try to make two or three objects reactive, with defineReactive, until it is okay here.

But when I try to change some values โ€‹โ€‹inside this object, the changes do not apply to the view. BUT if I explicitly call this. $ Bucket._state.projects .__ ob __. Dep.notify () , changes propagate.

The current view of the Vue instance object is as follows: Vue { $bucket: { _state: { projects: {} } } }

$bucket._state was initialized with defineReactive . which, I believe, should work, but I'm not sure exactly what the problem is in this case.

Any idea?

Partially of code, the class 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); } } } 
+7
source share
1 answer

I think you do not need to use these internal APIs like Vue.util.defineReactive or this.$bucket._state.projects.__ob__.dep.notify()

Since Vue itself is reactive, you can use an instance of Vue to store data. There is no need to reinvent the reactivity system.

Create an instance of Vue in the constructor:

 this.storeVM = new Vue({ data }) 

and use getter to delegate .state to storeVM.$data

 get state () { return this.storeVM.$data } 

so when you myPlugin.state to myPlugin.state , you myPlugin.state access Vue instance data.

I created a very simple reactive plugin example: http://codepen.io/CodinCat/pen/GrmLmG?editors=1010

There is no need to use defineReactive or notify dependencies yourself if the Vue instance can do everything for you. In fact, thatโ€™s how Vuex works.

+12
source share

All Articles