Computed props not working Vue JS 2

2019-07-18 12:29发布

im learning vue js following a channel on YT, the video was sent last year, so i think its not working due to some changes on VueJS itself, but it would be great if you guys could help me with this

codeio link: http://codepen.io/myrgato/pen/BWWxdQ

HTML

<script src="https://unpkg.com/vue@2.2.2"></script>
<div id="app">
  <button @click="increment">Increment</button>
  <p>Counter: {{counter}}</p>
  <p>Clicks: {{clicks}}</p>
</div>

JS

new Vue({
  el: '#app',
  data: {
    counter: 0,
    clicks: 0
  },
  methods: {
    increment(){
      this.clicks++;
    }
  },
  computed: {
    counter(){
      return this.clicks * 2; 
    }
  }
});

its supposed to calculate the amount of clicks, then use a computed proprerty to display a counter that equals clicks times two, but for some reason it isnt working..

3条回答
forever°为你锁心
2楼-- · 2019-07-18 13:00

Here is a working solution. The trick is to:

  • use a different name for the computed property (here counter2)
  • and to use a lambda function with a single parameter (here x) instead of this.

new Vue({
  el: '#app',
  data: {
    counter: 0,
    clicks: 0
  },
  methods: {
    increment() {
      this.clicks++;
    }
  },
  computed: {
    counter2: x => x.clicks * 2
  }
});
<script src="https://unpkg.com/vue@2.2.2"></script>
<div id="app">
  <button @click="increment">Increment</button>
  <p>Counter: {{counter2}}</p>
  <p>Clicks: {{clicks}}</p>
</div>

查看更多
ら.Afraid
3楼-- · 2019-07-18 13:16

Since I wasn't sure of why this happened I ran two tests on jsFiddle:

sample A:

sample B

Here you would notice that in sample B the order of execution is:

  1. Data properties get added first.
  2. The created hook is invoked.
  3. The computed property calculates the value of counter

In sample A, the step 3 never happens.

In vue2.1.0, you would get a warning like :

Vue warn: existing instance property "haveTrigger" will be overwritten by a computed property with the same name.


Further checking in the docs I found that this warning is suppressed in vue 2.2.2 hence you never received it, but along with it I found this interesting piece:

Props and computed properties are now defined on a component's prototype instead of as self properties on each instance. This avoids many calls to Object.defineProperty and improves component initialization performance. This will only affect you if you rely on hasOwnProperty checks on props and computed properties, which should be extremely rare, but we are documenting it here to be explicit about the change.

Source

var fancyConstructor = function () {
  this.value = 5
}

var instance = new fancyConstructor()

fancyConstructor.prototype.value = 5000
fancyConstructor.prototype.someOtherValue = 5000

console.log(instance.value)
console.log(instance.someOtherValue)

you can also go deep down in each component to find that there are indeed computed properties set to counter.

enter image description here

The above snippet will illustrate what happens if a property by the same name is there on the object as well as the prototype.

查看更多
SAY GOODBYE
4楼-- · 2019-07-18 13:25

Short but the full answer:

Never use the same name for data variable and computed.

Think about data & computed as the same object, so names can't be duplicated.

查看更多
登录 后发表回答