【问题标题】:How to Watch Object Property within a Vue Plugin如何在 Vue 插件中观察对象属性
【发布时间】:2020-02-04 19:53:59
【问题描述】:

背景

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

import SomeObject from "./SomeObject";

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

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

    }
}

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

问题和疑问

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

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

请注意,我不是在寻找以下答案,我已经知道这是可以做到的,但它破坏了将代码分离为插件的意义。一个全局的 mixin 也是不够的......

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

    }
}

【问题讨论】:

    标签: javascript vue.js watch


    【解决方案1】:

    在 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 实例?

    另一种方法是使用属性设置器而不是watch。想法是使用Object.defineProperty 为您想要“观察”的属性创建一个设置器,然后将您需要的任何副作用放入设置器中。

    【讨论】:

    • 非常感谢您的回答!我实际上想过创建一个单独的 Vue 实例,但我不确定新的 Vue 实例是否能够监听另一个 Vue 实例上定义的 observable ......我想避免 watch 属性的原因Vue 实例仅仅是因为我不想在我的组件上定义它,但是在一个单独的 Vue 实例上它绝对没问题,如果它当然可以工作的话。我现在会玩,如果我能够让它工作,我会回来接受:-D
    • 这个答案的主要警告是 vue 的每个实例现在都有 $someObject,而不仅仅是您创建的实例。这是不好的做法,因为它会饱和/污染 vue 对象的全局空间。
    • @Hybridwebdev 使$someObject 可通过每个 Vue 实例访问的设计决定是原始问题的一部分。在 Vue 2 上下文中,它是一种常用的模式,尽管出于您提到的原因,它确实需要谨慎使用。在即将到来的 Vue 3 中,这种模式已被侵入性较小的替代方案所取代。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多