Background
Consider the following, very basic, plugin:
import SomeObject from "./SomeObject";
/**
* Some Cool Plugin...
*/
export default {
install(Vue){
Vue.prototype.$someObject = Vue.observable(SomeObject);
}
}
The purpose of the above is to register an object to be reactive throughout my application.
The Problem & Question
Vue.prototype.$someObject
contains certain properties that need to be watched
, on a global level, not a ponent level.
Is there a way to attach a watcher to the Vue instance within the install
method of a Vue plugin?
Please note, I am not looking for the following answer, I am already aware this can be done but it defeats the point of separating the code into a plugin. A global mixin would also not be sufficient...
watch: {
'$someObject.foo': {
handler(value) {
console.log(value);
}
}
}
What I have Tried
Based on the documentation outlined here, I assumed I could do something along the lines of the following:
export default {
install(Vue){
Vue.prototype.$someObject = Vue.observable(SomeObject);
// I have tried all of the following:
Vue.watch(Vue.prototype.$someObject.foo, value => { console.log(value) });
Vue.$watch(Vue.prototype.$someObject.foo, value => { console.log(value) });
Vue.prototype.watch(Vue.prototype.$someObject.foo, value => { console.log(value) });
Vue.prototype.$watch(Vue.prototype.$someObject.foo, value => { console.log(value) });
Vue.watch(Vue.$someObject.foo, value => { console.log(value) });
Vue.$watch(Vue.$someObject.foo, value => { console.log(value) });
Vue.prototype.watch(Vue.$someObject.foo, value => { console.log(value) });
Vue.prototype.$watch(Vue.$someObject.foo, value => { console.log(value) });
}
}
Background
Consider the following, very basic, plugin:
import SomeObject from "./SomeObject";
/**
* Some Cool Plugin...
*/
export default {
install(Vue){
Vue.prototype.$someObject = Vue.observable(SomeObject);
}
}
The purpose of the above is to register an object to be reactive throughout my application.
The Problem & Question
Vue.prototype.$someObject
contains certain properties that need to be watched
, on a global level, not a ponent level.
Is there a way to attach a watcher to the Vue instance within the install
method of a Vue plugin?
Please note, I am not looking for the following answer, I am already aware this can be done but it defeats the point of separating the code into a plugin. A global mixin would also not be sufficient...
watch: {
'$someObject.foo': {
handler(value) {
console.log(value);
}
}
}
What I have Tried
Based on the documentation outlined here, I assumed I could do something along the lines of the following:
export default {
install(Vue){
Vue.prototype.$someObject = Vue.observable(SomeObject);
// I have tried all of the following:
Vue.watch(Vue.prototype.$someObject.foo, value => { console.log(value) });
Vue.$watch(Vue.prototype.$someObject.foo, value => { console.log(value) });
Vue.prototype.watch(Vue.prototype.$someObject.foo, value => { console.log(value) });
Vue.prototype.$watch(Vue.prototype.$someObject.foo, value => { console.log(value) });
Vue.watch(Vue.$someObject.foo, value => { console.log(value) });
Vue.$watch(Vue.$someObject.foo, value => { console.log(value) });
Vue.prototype.watch(Vue.$someObject.foo, value => { console.log(value) });
Vue.prototype.$watch(Vue.$someObject.foo, value => { console.log(value) });
}
}
Share
Improve this question
edited Jul 14, 2022 at 2:05
tony19
139k23 gold badges277 silver badges347 bronze badges
asked Oct 7, 2019 at 13:47
Ben CareyBen Carey
17k20 gold badges93 silver badges181 bronze badges
1 Answer
Reset to default 7In Vue 2 only Vue instances expose watch
. When Vue 3 arrives you'll have other options but for now you're stuck with using a Vue instance.
That said, you can have an instance within the plugin, so it should be easy enough to achieve what you want:
import Vue from 'vue';
import SomeObject from './SomeObject';
/**
* Some Cool Plugin...
*/
export default {
install (Vue) {
Vue.prototype.$someObject = Vue.observable(SomeObject);
new Vue({
watch: {
'$someObject.foo' () {
// Do something
}
}
})
}
}
The Vue instance created here is not being rendered. It exists purely to give us a way to watch $someObject
.
I know you ruled this out in the question but I don't really understand why. Perhaps you weren't envisaging creating a dedicated Vue instance specially for the purposes of watching?
An alternative would be to use property setters instead of watch
. The idea there would be to use Object.defineProperty
to create a setter for the properties you want to 'watch' and then put whatever side-effects you need within the setter.