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

javascript - Vue2 watch Set Not Working - Stack Overflow

programmeradmin7浏览0评论

I have a simple Vue app that is supposed to add a number to a Set when you click the "Add to Set" button --

<div id="app">
  <input type="number" placeholder="enter a number" v-model="n">
  <button type="button" @click.prevent="addToSet()">Add to Set</button>
</div>

new Vue({
  el: "#app",
  data: {
    n: null,
    nSet: new Set()
  },
  methods: {
    addToSet: function() {
      this.nSet.add(this.n);
      console.log(this.n + ' added to Set');
    }
  },
  watch: {
    nSet: function (newVal, oldVal) {
      console.log(newVal);
    }
  }
});

Why is nothing logged in the console by the watch?

I have a simple Vue app that is supposed to add a number to a Set when you click the "Add to Set" button --

https://codepen.io/jerryji/pen/mKqNvm?editors=1011

<div id="app">
  <input type="number" placeholder="enter a number" v-model="n">
  <button type="button" @click.prevent="addToSet()">Add to Set</button>
</div>

new Vue({
  el: "#app",
  data: {
    n: null,
    nSet: new Set()
  },
  methods: {
    addToSet: function() {
      this.nSet.add(this.n);
      console.log(this.n + ' added to Set');
    }
  },
  watch: {
    nSet: function (newVal, oldVal) {
      console.log(newVal);
    }
  }
});

Why is nothing logged in the console by the watch?

Share Improve this question asked Jun 18, 2018 at 13:49 Jerry JiJerry Ji 3861 gold badge3 silver badges15 bronze badges 3
  • 1 Is there any reason why you're using Set over Array? If the sole purpose is to ensure uniqueness, you can easily check with indexOf before pushing. AFAIK there is no easy way to watch for Set changes. – Terry Commented Jun 18, 2018 at 14:06
  • Because Set is required in the actual code. The codepen is just a stripped down example. But I got your point. Thanks – Jerry Ji Commented Jun 18, 2018 at 14:30
  • Wondering if Sets are non reactive within Vue ponents. – Francis Leigh Commented Jun 18, 2018 at 14:44
Add a ment  | 

3 Answers 3

Reset to default 4

Saving and re Setting the Set using the .values() method on Set worked for me and i didn't have to use $forceUpdate

Using $forceUpdate might be the more sensible way to go though. In some use cases in the past i have found forcing ponents to update to be problematic.

new Vue({
  el: "#app",
  data: {
    n: null,
    nSet: new Set()
  },
  methods: {
    addToSet: function() {
      let set = this.nSet;
      let newSet = set.add(this.n)
      this.nSet = new Set(newSet.values())
    }
  },
  watch: {
    nSet: function (newVal, oldVal) {
      console.log('newVal', ...newVal);
    }
  }
});
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.16/vue.min.js"></script>


<div id="app">
  <input type="number" placeholder="enter a number" v-model="n">
  <button type="button" @click.prevent="addToSet()">Add to Set</button>
  <p>n = {{ n }}</p>
</div>

Vue adds special handling for Arrays, but not for Sets. As a result, Vue doesn't automatically detect changes to Set membership. You can force an update, though

  this.nSet.add(this.n);
  this.$forceUpdate();

It's because Vue doesn't support Set, Map, WeakSet and WeakMap. And it's because browsers didn't support these structures well. Especially WeakMap. But... They decided to support these structures. Maybe in version 3 - when they decide to drop support for older browsers. So, for now use an object, add properties with Vue.$set() and watch for changes with deep: true.

发布评论

评论列表(0)

  1. 暂无评论