Vuejs 및 Vue.set (), 배열 업데이트


94

저는 Vuejs를 처음 사용합니다. 무언가를 만들었지 만 그것이 간단하고 올바른 방법인지 모르겠습니다.

내가 원하는 것

배열의 날짜를 원하고 이벤트에서 업데이트합니다. 먼저 Vue.set을 시도했지만 작동하지 않습니다. 이제 내 배열 항목을 변경 한 후 :

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

배열에 아무 것도 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>

답변:


59

이와 같이 배열을 조작하면 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

1
PLS는 하드 코드를 읽을 만들기, 탭의 크기가 SE 앱에서 분명히 다른, 공간 들여 쓰기와 탭 들여 쓰기를 결합하지 않습니다
Ferrybig

제 경우에는 푸시 작업을위한 ES6 스프레드 연산자가 vue에서 제대로 작동하지 않습니다
Mathias S

117

2 편집

  • 의 경우 모든 개체가 필요 반응성 사용 변경Vue.set(object, prop, value)
  • 배열 변형의 경우 여기 에서 현재 지원되는 목록을 볼 수 있습니다.

1 편집

vuex의 경우에는 Vue.set(state.object, key, value)


실물

이 질문에 오는 다른 사람들에게만 해당됩니다. 그것은 그들이 제거 * 뷰 2의 어느 시점에 나타납니다 this.items.$set(index, val)찬성 this.$set(this.items, index, val).

Splice는 여전히 사용할 수 있으며 여기에 vue 링크 에서 사용할 수있는 배열 변형 방법에 대한 링크가 있습니다 .


'색인'으로 제공해야하는 문자열은 무엇입니까?
Kokodoko

@Kokodoko 당신이하려는 일을 명확히 할 수 있습니까? 배열 인 경우 인덱스의 숫자 여야합니다. 객체에 필드를 설정하는 경우 문자열이됩니다.
Martin Calvert

아, 내 IDE는 그것이 문자열이어야한다고 주장했습니다. 결함 일 것입니다.
Kokodoko

Vue.set은 vuex 용이 아닙니다. 그리고 this. $ set는 더 이상 사용되지 않습니다.
atilkan

2
@MartinCalvert "객체에 속성을 추가 할 때"라고합니다. 이것이 Vue.set의 주요 목적이며, vuex와 관련이 없습니다. Deprecation, 나는 그것을 링크에서 읽었지만 지금 다시 읽고, 나는 그것을 완전히 이해하지 못합니다. stackoverflow.com/questions/36671106/…
atilkan

11

앞서 언급했듯이-VueJS는 단순히 이러한 작업 (배열 요소 할당)을 추적 할 수 없습니다. 배열로 VueJS에서 추적하는 모든 작업이 여기에 있습니다 . 하지만 다시 한 번 복사하겠습니다.

  • 푸시()
  • 팝()
  • 시프트()
  • unshift ()
  • 접착()
  • 종류()
  • 역전()

개발하는 동안 문제에 직면합니다-어떻게 살아가는가 :).

push (), pop (), shift (), unshift (), sort () 및 reverse ()는 매우 평범하며 경우에 따라 도움이되지만 주요 초점은 splice ()에 있습니다. 있으므로 배열을 효과적으로 수정할 수 있습니다 VueJ가 추적합니다. 그래서 저는 배열에 가장 많이 사용되는 접근 방식을 공유 할 수 있습니다.

배열의 항목을 교체해야합니다.

// 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

문제에 대한 한 가지 대안이자보다 가벼운 접근 방식은 배열을 일시적으로 편집 한 다음 전체 배열을 다시 변수에 할당하는 것입니다. Vue는 개별 항목을 보지 않기 때문에 전체 변수가 업데이트되는 것을 감시합니다.

따라서 이것도 작동합니다.

var tempArray[];

tempArray = this.items;

tempArray[targetPosition]  = value;

this.items = tempArray;

그러면 DOM도 업데이트됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.