Description
Update:
If anyone ends up needing this functionality, I've released it as vue-nonreactive with the appropriate admonitions and everything.
We have some non-plain models where we need to disable Vue's observation and walking. An example is a resource model that has access to a cache so that it can lookup related resources. This causes all of the objects in the cache to become watched (probably inefficient), as well as some additional interactions with other code. Currently, we get around this by setting a dummy Observer on the cache. Something similar to...
import get from 'http';
import Resource from 'resource';
new Vue({
data: { instance: {}, },
ready() { this.fetch(); },
methods: {
fetch() {
const Observer = Object.getPrototypeOf(this.instance.__ob__).constructor;
get('/api/frobs')
.then(function(data) {
// initialize Resource w/ JSON document
const resource = new Resource(data);
// Protect cache with dummy observer
resource.cache.__ob__ = new Observer({});
this.instance = resource;
});
},
},
});
This does work, but
- relies on vue's internals
- requires an already observed object since we cannot import the
Observer
class directly.
Proposal:
Add an official method for explicitly disabling Vue's observation/walking. eg, something like...
const someThing = {
nestedThing: {},
};
// make entire object non-reactive
Vue.nonreactive(someThing);
// make nested object non-reactive
Vue.nonreactive(someThing.nestedThing);
vm.$set('key.path', someThing);
Considerations:
-
What should happen if a user set a reactive key path to an non-reactive object? Should vue warn the user? eg,
vm.$set('a', Vue.nonreactive({}); // different from.. vm.$set('a', { someKey: Vue.nonreactive({}), });
-
Should an already reactive object warn the user if attempted to be made non-reactive? eg,
// error
Vue.nonreactive(vm.$data.a)
// valid
Vue.nonreactive(_.clone(vm.$data.a));