最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to Watch Object Property within a Vue Plugin - Stack Overflow

programmeradmin4浏览0评论

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
Add a ment  | 

1 Answer 1

Reset to default 7

In 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.

发布评论

评论列表(0)

  1. 暂无评论