如何在 Vue 插件中观察对象 属性

How to Watch Object Property within a Vue Plugin

背景

考虑以下非常基本的插件:

import SomeObject from "./SomeObject";

/**
 * Some Cool Plugin...
 */
export default {
    install(Vue){

        Vue.prototype.$someObject = Vue.observable(SomeObject);

    }
}

上面的目的是注册一个在我的应用程序中反应的对象。

问题与疑问

Vue.prototype.$someObject 包含需要 watched 在全局级别而不是组件级别的某些属性。

有没有办法在 Vue 插件的 install 方法中将观察者附加到 Vue 实例?

请注意,我不是寻找以下答案,我已经知道这可以完成,但它破坏了将代码分离到插件中的意义。全局混合也不够...

watch: {

    '$someObject.foo': {
        handler(value) {
            console.log(value);
        }
    }

}

我试过的

根据概述的文档 here,我认为我可以按照以下方式做一些事情:

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) });

    }
}

在 Vue 2 中,只有 Vue 实例公开 watch。当 Vue 3 到来时,您将有其他选择,但现在您只能使用 Vue 实例。

也就是说,你可以在插件中有一个实例,所以应该很容易实现你想要的:

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
            }
          }
        })
    }
}

这里创建的Vue实例没有被渲染。它的存在纯粹是为了给我们一种观看方式$someObject.

我知道你在问题中排除了这一点,但我真的不明白为什么。或许您并没有设想专门为观看目的创建一个专用的 Vue 实例?

另一种方法是使用 属性 setter 代替 watch。想法是使用 Object.defineProperty 为您想要 'watch' 的属性创建一个 setter,然后将您需要的任何副作用放入 setter.