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

javascript - Add watcher to dynamically created object - Stack Overflow

programmeradmin2浏览0评论

At some point in time of the ponent’s work, one of its values ​​from the primitive turns into an object. This object is dynamically assigned fields with values. It is necessary to track the change in these values.

Simplified code to reproduce the problem:

const fields = ['name', 'age'];

const app = new Vue({
  el: '#app',
  data() {
    return {
      value: '',
    };
  },
  watch: {
    value: function() {
      console.log('Global: Value changed');
    },
  },
  mounted() {
    this.value = '111';
    this.value = {};
    fields.forEach(field => {
      this.value[field] = '';
    });

    this.$watch('value', callback, { deep: true });
    function callback() {
      console.log('Callback: Value changed');
    }

    this.$nextTick(() => {
      this.value.name = 'Max';
      this.value.age = 30;
      console.log(this.value)
    });
  },
});
<script src="/[email protected]"></script>

<div id="app"></div>

At some point in time of the ponent’s work, one of its values ​​from the primitive turns into an object. This object is dynamically assigned fields with values. It is necessary to track the change in these values.

Simplified code to reproduce the problem:

const fields = ['name', 'age'];

const app = new Vue({
  el: '#app',
  data() {
    return {
      value: '',
    };
  },
  watch: {
    value: function() {
      console.log('Global: Value changed');
    },
  },
  mounted() {
    this.value = '111';
    this.value = {};
    fields.forEach(field => {
      this.value[field] = '';
    });

    this.$watch('value', callback, { deep: true });
    function callback() {
      console.log('Callback: Value changed');
    }

    this.$nextTick(() => {
      this.value.name = 'Max';
      this.value.age = 30;
      console.log(this.value)
    });
  },
});
<script src="https://cdn.jsdelivr/npm/[email protected]"></script>

<div id="app"></div>

Share Improve this question asked Aug 30, 2019 at 10:34 DmytroDmytro 3726 silver badges15 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

The critical line is this.value = .... That's the point where the object will be made reactive and all properties need to exist at that point.

Here I've tweaked that section to add the properties before assigning the object to this.value.

const fields = ['name', 'age'];

const app = new Vue({
  el: '#app',
  data() {
    return {
      value: '',
    };
  },
  watch: {
    value: function() {
      console.log('Global: Value changed');
    },
  },
  mounted() {
    this.value = '111';

    const value = {}

    fields.forEach(field => {
      value[field] = '';
    });

    this.value = value;

    this.$watch('value', callback, { deep: true });
    function callback() {
      console.log('Callback: Value changed');
    }

    this.$nextTick(() => {
      this.value.name = 'Max';
      this.value.age = 30;
      console.log(this.value)
    });
  },
});
<script src="https://cdn.jsdelivr/npm/[email protected]"></script>

<div id="app"></div>

Alternatively you can use this.$set to set them later: https://v2.vuejs/v2/api/#vm-set.

Vue.$set(object, key, value) can be helpful here:

const fields = ['name', 'age'];

const app = new Vue({
  el: '#app',
  data() {
    return {
      value: '',
    };
  },
  watch: {
    value: {
      handler: function(value) {
        console.log('Global: Value changed', value);
      },
      deep: true
    }
  },
  mounted() {
    let value = {};
    fields.forEach(field => {
      value[field] = '';
    });

    this.$set(this, 'value', value);

    this.$nextTick(() => {
      this.value.name = 'Max';
      this.value.age = 30;
      console.log(this.value)
    });
  },
});
<script src="https://cdn.jsdelivr/npm/[email protected]"></script>

<div id="app"></div>

this is called reactivity Caveat

https://v2.vuejs/v2/guide/reactivity.html#Change-Detection-Caveats

so to solve this issue you can import vue

import Vue from 'vue'

and then where you want to change values of an object

fields.forEach(field => {
  //this.value[field] = ''; // instead of this
    Vue.set(this.value, 'field', '')
});

OR

this.$set(this.value, 'field', '')
发布评论

评论列表(0)

  1. 暂无评论