質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Vue CLI

Vue CLIは、Vue.jsでアプリケーション開発を行うためのコマンドラインインタフェース(CLI)に基づいた開発ツールです。インタラクティブなプロジェクトの雛形や設定なしで使用できるプロトタイプの作成など、さまざまな機能が用意されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

1187閲覧

vue .js 配列の値が期待通りに変更できない

kurimaron7

総合スコア14

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Vue CLI

Vue CLIは、Vue.jsでアプリケーション開発を行うためのコマンドラインインタフェース(CLI)に基づいた開発ツールです。インタラクティブなプロジェクトの雛形や設定なしで使用できるプロトタイプの作成など、さまざまな機能が用意されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/02/16 12:22

前提・実現したいこと

サンプルコードを書いているのですが、想定した通りの挙動になりません。

サンプルコードの任意の<div>のクリックイベントで、対象メソッドを呼び出して処理を行う箇所の挙動がおかしくなってしまいます。具体的には、一度のクリックで全ての配列の値が変更されてしまいます。
2、3回クリックすると、想定の挙動になります。

上記のサンプルコードで行いたいことは下記の通りです。

  • 配列の各値に対してv-forで繰り返し<div>として表示する。
  • 任意の<div>をクリックした場合、値の真偽により処理を分ける。
  1. 真の場合、そのdivにバインドしている配列要素を削除する。
  2. 偽の場合、divにバインドしている値を変更する(真偽や、他のプロパティの値を書き換える処理)。

気になること

配列の各値に、ユニークなキーを保持していないことが原因なのかと思っています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

created フックで以下のように配列を初期化していますが、ここに間違いがあります。

javascript

1this.dataLists = this.dataLists.fill({ isactive: false, task: "none" });

おそらく長さ12 の配列である dataLists に、12個のオブジェクトを作って設定する、ということを意図されているのだと思いますが、実際にご提示のコードで作成されるオブジェクトは 1個だけで、そのオブジェクトへの参照を dataLists[0] ~ dataLists[11] に設定しています。

結果、dataLists のすべての要素は同じ要素への参照を持ってしまい、要素の変更に対して配列全体が変更を受けた可能用に見えてしまっています。

数回クリックした際に想定通りの動作になるのは、callSelect 内の else ブロックで新たなオブジェクトを生成して設定しているためです(ここで変更されなかった部分については依然問題が発生するはずです)。

以下のように12個それぞれに別のオブジェくトを作成して配列に設定してください。

javascript

1for (let i=0; i<this.dataLists.length; i++) { 2 this.$set(this.dataLists, i, { isactive: false, task: "none" }) 3 // this.dataLists[i] = { ... } とすると、 4 // Vue.js が変更を検知できない可能性があります。 5 // そのため、this.$set() を利用します 6 // 7 // ループの中でオブジェクトを定義しているのがポイントです。 8}

投稿2020/02/16 14:54

R.Mizukami

総合スコア1086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kurimaron7

2020/02/17 12:56

回答ありがとうございます。 回答通りに修正したところ、解決いたしました。 下記追加で2点ほどお聞きしたいのですが、余談ですので回答いただけなくとも後日ベストアンサーにさせていただきます。 ①fillにオブジェクトではなくプリミティブ型の単一データを引数とした場合は、値渡しとして 各配列の要素が独立した値になると考えて良いでしょうか?(fillのリファレンスを見たところ、オブジェクトの場合だけが参照コピーとなると記述されていましたので) ②今回の回答例では、for文で配列を回数文操作していますが、forEachや他の配列操作系メソッドでも代用可能でしょうか? ご回答いただけますと幸いです。
R.Mizukami

2020/02/17 14:56 編集

①はい。プリミティブ型ならこのような現象は起こりません。 ②はい。ただし new Array(12).map(() => ({ isActive: true, task: "none"})) や new Array(12).forEach( ~ ) などとすると、おそらく想定外の動作をするので注意が必要です。(詳しくはこちらをご参考ください→ https://qiita.com/s-shin/items/88b2b6d4387312fe000a )
kurimaron7

2020/02/18 03:13

ありがとうございます! とても参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問