1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Vue.js】複数のカウントボタンを、それぞれ押下した数だけカウントさせたい【Component】

Posted at

問題

Vue.jsのComponentの勉強のため、カウンターを作っていたときのことです。

1つのボタンを押したら、他のボタンのカウントも増えてしまう問題が発生。

20200304_vue_before.gif

環境

  • Vue.js v2.6.11(CDN)

コード

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Components</title>
  <link rel="stylesheet" href="css/styles.css">
</head>
<body>
  <div id="app">
    <button-counter message="Counter A"></button-counter>
    <button-counter message="Counter B"></button-counter>
    <button-counter message="Counter C"></button-counter>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
  <script src="js/main.js"></script>
</body>
</html>
js/main.js
(function () {
  'use strict';

  const counter = {
    count: 0
  };

  const countComponent = Vue.extend({
    template: '<button @click="countUp">{{ message }}: {{ count }}</button>',
    props: {
      message: {
        type: String,
      },
    },
    data: function () {
      return counter;
    },
    methods: {
      countUp: function () {
        this.count++;
      },
    },
  });

  const vm = new Vue({
    el: '#app',
    components: {
      'button-counter': countComponent,
    },
  });
})();

原因

リファレンスを読むと、

コンポーネントの data オプションは関数でなければなりません。各インスタンスが返されるデータオブジェクトの独立したコピーを保持できるためです:

という記述がありました。
参照:【Vue.js ガイド】data は関数でなければなりません

それぞれのカウントボタンインスタンスに返される値を独立させるために、dataオプションを関数にしなければならないのですね。

解決

リファレンスに記述の仕方がちゃんと書いてありました。

data: function () {
return {
count: 0
}
}

Vue にこのルールがない場合、ボタンを1つクリックすると、以下のようにすべての他のインスタンスのデータに影響します:

丁寧に今回の事象の例も提示してありました。


修正後はこうなりました。

``````js:js/main.js
(function () {
  'use strict';

  // 削除
  // const counter = {
  //   count: 0
  // };

  const countComponent = Vue.extend({
    template: '<button @click="countUp">{{ message }}: {{ count }}</button>',
    props: {
      message: {
        type: String,
      },
    },
    // 変更-----
    data: function () {
      return {
        count: 0,
      };
    },
    // -----
    methods: {
      countUp: function () {
        this.count++;
      },
    },
  });

  const vm = new Vue({
    el: '#app',
    components: {
      'button-counter': countComponent,
    },
  });
})();

ちゃんとそれぞれのボタンの押下数をカウントしてくれるようになりました。
20200304_vue_after.gif

反省

ちなみにcountComponentの中でdataオプションを関数にしないままcountを定義しようとすると、Vue.jsの方でReferenceError: count is not definedと、エラーになることを教えてくれました。
スクリーンショット 2020-03-04 16.47.22.png

そもそも、countは別で定義するのではなく、処理をしているインスタンス内で設定すればよかったのですね。

参照

【Vue.js ガイド】data は関数でなければなりません

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?