130
81

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 5 years have passed since last update.

Vueの配列の変更が反映されないんだが

Last updated at Posted at 2019-02-01

最終的にやりたかったこと

ツリー表示して選択されたデータを反映

tree_select.gif

公式のツリーのサンプル

https://jp.vuejs.org/v2/examples/tree-view.html
は使いたくないんだ
確かに楽なんだけど子コンポーネント孫コンポーネント作っちゃうと
データのバケツリレーになるからVuexを使わなければいけなくなるではないか。。。!
なので子コンポーネント化せずにがんばった

やってみた

動かない
v-forでリストレンダリングしてるツリー構造の部分がクリックしても開閉せず
しかしクリックイベントは拾ってデータの変更はされている
配列がリアクティブじゃないぞ。。。。

配列の挙動の検証

<template>
  <div>
    <ul>
      <li v-for="(item, index) in list" :key="index"> {{ item }} </li>
    </ul>
    {{ list }}
    <button @click="incrementArray">+1</button>
  </div>
</template>

<script>
export default {
  name: 'Sample',
  data() {
    return {
      list: [1, 2, 3, 4, 5]
    }
  },
  methods: {
    incrementArray() {
      this.list[0] = this.list[0] + 1;
      console.log(this.list);
    }
  }
}
</script>

ezgif-5-117cc6db901f.gif

あかん、反映されへんぞ。。。なんやこれ。。。

しかしコンソールログを見ると値は増えてるから
原因は再描画されていないことだな

調べた参考になる記事

要するに

push()
pop()
shift()
unshift()
splice()
sort()
reverse()
を使えば変更を検知して再描画するぞ!!

  • 普通に代入すると検知しないぞ!!
  • 配列とオブジェクトに要素を増やしたり減らしたりするときはthis.$set()を使え!!」

なるほどね

修正していく

上記メソッド無駄に走らせて強制発火パターン

<script>
export default {
  name: 'Sample',
  data() {
    return {
      list: [1, 2, 3, 4, 5]
    }
  },
  methods: {
    incrementArray() {
      this.list[0] = this.list[0] + 1;
      this.list.splice();
    }
  }
}
</script>

ezgif-5-8066f97e8ad1.gif
おお〜

一見イケてない実装だけど
表示してる配列に変更はないけど別の変数の状態が表示に影響している場合は
こうするしかないかもしれない
v-forの中で別の変数をv-showv-ifで参照してる時とか

this.list.push({});
this.list.pop();

とか

this.list.unshift({});
this.list.shift();

とか試したけど
強制発火させるならsplice()が一番速かった

this.$setを使うパターン

<script>
export default {
  name: 'Sample',
  data() {
    return {
      list: [1, 2, 3, 4, 5]
    }
  },
  methods: {
    incrementArray() {
      this.$set(this.list, 0, this.list[0] + 1);
    }
  }
}
</script>

表示に使っているデータに変更を直接加える場合はこれがいい
あとは上記メソッド使ったり

配列とオブジェクトは特殊なんですね

次回はツリー表示したチェックボックスのやつの記事でも書きます
渋ってないでツリーを子コンポーネント化してVuexデビューしようかな。。。

130
81
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
130
81

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?