VuejsとVue.set()、配列を更新


92

私はVuejsを初めて使用します。何かを作ったが、それが簡単で正しい方法かどうかはわからない。

私が欲しいもの

配列にいくつかの日付が必要で、イベントでそれらを更新します。最初にVue.setを試しましたが、うまくいきませんでした。配列アイテムを変更した後:

this.items[index] = val;
this.items.push();

配列に何もプッシュ()しないと更新されます。しかし、最後の項目が非表示になることがあります。どういうわけか...このソリューションは少しハックだと思います。どうすれば安定させることができますか?

簡単なコードはここにあります:

new Vue({
  el: '#app',
  data: {
  	f: 'DD-MM-YYYY',
    items: [
      "10-03-2017",
      "12-03-2017"
    ]
  },
  methods: {
    
    cha: function(index, item, what, count) {
    	console.log(item + " index > " + index);
      val = moment(this.items[index], this.f).add(count, what).format(this.f);
  		this.items[index] = val;
      this.items.push();
      console.log("arr length:  " + this.items.length);
    }
  }
})
ul {
  list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<div id="app">
  <ul>
    <li v-for="(index, item) in items">
    <br><br>
      <button v-on:click="cha(index, item, 'day', -1)">
      - day</button>
      {{ item }}
      <button v-on:click="cha(index, item, 'day', 1)">
      + day</button>
    <br><br>
    </li>
  </ul>
</div>

回答:


57

このように配列を操作すると、VueJSは状態への変更を取得できません。

Common Beginner Gotchasで説明されているように、push、spliceなどの配列メソッドを使用し、このようなインデックスやa[2] = 2配列の.lengthプロパティを変更しないでください。

new Vue({
  el: '#app',
  data: {
    f: 'DD-MM-YYYY',
    items: [
      "10-03-2017",
      "12-03-2017"
    ]
  },
  methods: {

    cha: function(index, item, what, count) {
      console.log(item + " index > " + index);
      val = moment(this.items[index], this.f).add(count, what).format(this.f);

      this.items.$set(index, val)
      console.log("arr length:  " + this.items.length);
    }
  }
})
ul {
  list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<div id="app">
  <ul>
    <li v-for="(index, item) in items">
      <br><br>
      <button v-on:click="cha(index, item, 'day', -1)">
      - day</button> {{ item }}
      <button v-on:click="cha(index, item, 'day', 1)">
      + day</button>
      <br><br>
    </li>
  </ul>
</div>


1
ドキュメントで述べられているように、$ setはかなりの.splice()です。ドキュメントで言われているように、そのメソッドを使用して配列を変更する必要があるため、これは理にかなっています。
Borjante 2017年

1
plsはタブインデントとスペースインデントを組み合わせません。タブのサイズはSEアプリでは明らかに異なり、コードを読みにくくします
Ferrybig 2017年

私の場合、プッシュ動作のためのES6スプレッド-演算子は、VUEとproberly動作しません
マティアスS

116

編集2

  • 以下のためのすべてのオブジェクトその必要性反応の使用を変更しますVue.set(object, prop, value)
  • 配列の変異については、現在サポートされているリストをここで確認できます

編集1

vuexの場合はやりたいと思うでしょう Vue.set(state.object, key, value)


元の

だから、この質問に来る他の人のためだけに。Vue 2. *のある時点で表示さthis.items.$set(index, val)this.$set(this.items, index, val)ます。

スプライスは引き続き利用可能であり、vuelinkで利用可能な配列ミューテーションメソッドへのリンクがあります。


'インデックス'としてどの文字列を提供する必要がありますか?
ココドコ2018

@ココドコあなたがやろうとしていることを明確にできますか?配列の場合は、インデックスの数値である必要があります。文字列は、オブジェクトにフィールドを設定する場合に使用されます。
マーティンカルバート

ああ、私のIDEは、文字列である必要があり、グリッチである必要があると主張しました。
ココドコ2018

Vue.setはvuex用ではありません。そしてthis。$ setは非推奨になりました。
localhoost 2018年

2
@MartinCalvert「オブジェクトにプロパティを追加するとき」と表示されます。これがVue.setの主な目的であり、vuexだけに関係するものではありません。非推奨、リンクで読んだのですが、もう一度読んでいるので、完全には理解していません。stackoverflow.com/questions/36671106/...
localhoost

10

前に述べたように-VueJSは単にそれらの操作(配列要素の割り当て)を追跡できません。配列を使用してVueJSによって追跡されるすべての操作はここにあります。しかし、もう一度コピーします。

  • 押す()
  • ポップ()
  • シフト()
  • unshift()
  • スプライス()
  • ソート()
  • 逆行する()

開発中に、あなたは問題に直面します-それと一緒に暮らす方法:)。

push()、pop()、shift()、unshift()、sort()、reverse()は非常にわかりやすく、場合によっては役立ちますが、主な焦点はsplice()内にあり、配列を効果的に変更できます。それはVueJsによって追跡されます。したがって、配列で最もよく使用されるアプローチのいくつかを共有できます。

配列内のアイテムを置き換える必要があります。

// note - findIndex might be replaced with some(), filter(), forEach() 
// or any other function/approach if you need 
// additional browser support, or you might use a polyfill
const index = this.values.findIndex(item => {
          return (replacementItem.id === item.id)
        })
this.values.splice(index, 1, replacementItem)

注:アイテムフィールドを変更する必要がある場合は、次の方法で変更できます。

this.values[index].itemField = newItemFieldValue

そして、これは、item(Object)フィールドが追跡されるため、VueJSによって追跡されます。

配列を空にする必要があります。

this.values.splice(0, this.values.length)

実際には、この関数splice()を使用するとさらに多くのことができます-w3schools link 複数のレコードを追加したり、複数のレコードを削除したりできます。

Vue.set()およびVue.delete()

Vue.set()およびVue.delete()は、UIバージョンのデータにフィールドを追加するために使用される場合があります。たとえば、オブジェクト内に追加の計算データまたはフラグが必要です。これは、オブジェクトまたはオブジェクトのリスト(ループ内)に対して実行できます。

 Vue.set(plan, 'editEnabled', true) //(or this.$set)

そして、編集したデータを同じ形式でバックエンドに送り返します。これは、Axios呼び出しの前に行います。

 Vue.delete(plan, 'editEnabled') //(or this.$delete)

0

1つの代替方法(および問題に対するより軽量なアプローチ)は、配列を一時的に編集してから、配列全体を変数に割り当てることです。Vueは個々のアイテムを監視しないため、更新されている変数全体を監視します。

したがって、これも機能するはずです。

var tempArray[];

tempArray = this.items;

tempArray[targetPosition]  = value;

this.items = tempArray;

これにより、DOMも更新されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.