Vue가 배열이나 객체의 변경 사항을 감지할 수 없는 문제를 해결하는 방법은 무엇입니까?

亚连
풀어 주다: 2018-06-04 16:32:15
원래의
2177명이 탐색했습니다.

아래에서는 Vue가 배열이나 객체의 변경 사항을 감지하지 못하는 문제를 해결하는 기사를 공유하겠습니다. 이는 좋은 참고 가치가 있으며 모든 사람에게 도움이 되기를 바랍니다.

예를 살펴보겠습니다.

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>vue</title>
 <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script>
 <style>
 li:hover {
  cursor: pointer;
 }
 </style>
</head>
<body>
 <p class="wrap">
 <ul>
  <li v-for="item,index in items" v-on:click="handle(index)">
  <span>{{item.name}}</span>
  <span>{{numbers[index]}}</span>
  </li>
 </ul>
 </p>
 <script>
 var vm = new Vue({
  el: ".wrap",
  data: {
  numbers: [],
  items: [
   {name: &#39;jjj&#39;},
   {name: &#39;kkk&#39;},
   {name: &#39;lll&#39;},
  ]
  },
  methods: {
  handle: function (index) {
   // WHY: 更新数据,view层未渲染,但通过console这个数组可以发现数据确实更新了
   if (typeof(this.numbers[index]) === "undefined" ) {
   // 注:下面这么设置是可以的。例如 
   // var arr = [];
   // arr[3]=3;
   // console.log(arr) //[empty × 3, 3]
    this.numbers[index] = 1; 
   // this.numbers.splice(index,0,1) //用splice方法能同步显示,但得不到想要的效果
   } else {
    this.numbers[index]++;
   // this.numbers.splice(index,1,this.numbers[index]++)
   }
  // console.log(this.numbers)
  }
  }
 });
 
 </script>
</body>
</html>
로그인 후 복사

얻고자 하는 효과는 li를 클릭하여 vm.nymbers[index]가 존재하는지 확인하는 것입니다. 존재하지 않는 경우 1로 설정합니다. 존재한다면 1을 더하세요.

클릭 후 뷰 레이어에서는 숫자가 업데이트되지 않았습니다. 그러나 콘솔 인쇄를 통해 데이터가 업데이트되었지만 뷰 레이어에서는 이를 제때 감지하지 못한 것으로 나타났습니다.

또 다른 변경 사항을 살펴보세요:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>vue</title>
 <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script>
 <style>
 li:hover {
  cursor: pointer;
 }
 </style>
</head>
<body>
 <p class="wrap">
 <ul>
  <li v-for="item,index in items" v-on:click="handle(index)">
  <span>{{item.name}}</span>
  <!--<span>{{numbers[index]}}</span>-->
  </li>
 </ul>
 </p>
 <script>
 var vm = new Vue({
  el: ".wrap",
  data: {
  // numbers: [],
  items: [
   {name: &#39;jjj&#39;},
   {name: &#39;kkk&#39;},
   {name: &#39;lll&#39;},
  ]
  },
  methods: {
  handle: function (index) {
   // 不是数组,这里更新数据就可以直接在view层渲染
   this.items[index].name += " success";
  // console.log(this.numbers)
  }
  }
 });
 </script>
</body>
</html>
로그인 후 복사

여기서 뷰 레이어는 시간에 맞춰 업데이트할 수 있지만 배열의 경우 왜 업데이트할 수 없나요?

Vue2.0의 공식 문서를 살펴보세요:

JavaScript 제한으로 인해 Vue는 다음과 같은 변경된 배열을 감지할 수 없습니다.

색인을 사용하여 항목을 직접 설정하는 경우(예: vm.items) [indexOfItem ] = newValue

배열의 길이를 수정하는 경우, 예를 들어 vm.items.length = newLength

첫 번째 유형의 문제를 해결하려면 다음 두 가지 방법을 사용하면 vm과 동일한 효과를 얻을 수 있습니다. items[indexOfItem] = newValue , 상태 업데이트도 트리거합니다:

// Vue.set 
Vue.set(example1.items, indexOfItem, newValue)
로그인 후 복사
// Array.prototype.splice 
example1.items.splice(indexOfItem, 1, newValue)
로그인 후 복사

전역 Vue.set의 별칭인 vm.$set 인스턴스 메서드를 사용할 수도 있습니다.

또는 JavaScript 제한으로 인해 Vue는 객체 속성의 추가 또는 삭제를 감지할 수 없습니다.

var vm = new Vue({
 data: {
 a: 1
 }
})
// `vm.a` 现在是响应式的
vm.b = 2
// `vm.b` 不是响应式的
로그인 후 복사

이미 생성된 인스턴스의 경우 Vue는 루트 수준 반응형 속성을 동적으로 추가할 수 없습니다. 그러나 Vue.set(object, key, value) 메서드를 사용하여 중첩된 객체에 반응형 속성을 추가할 수 있습니다. 예를 들면 다음과 같습니다.

var vm = new Vue({ 
 data: { 
 userProfile: { 
  name: &#39;Anika&#39; 
 } 
 } 
})
로그인 후 복사

때로는 Object.sign() 또는 _.extend()를 사용하는 등 기존 개체에 여러 개의 새 속성을 할당해야 할 수도 있습니다. 이 경우 두 개체의 속성을 모두 사용하여 새 개체를 만들어야 합니다. 따라서 새로운 반응형 속성을 추가하려면 다음과 같이 표시하는 대신

Object.assign(this.userProfile, { 
 age: 27, 
 favoriteColor: &#39;Vue Green&#39; 
})
로그인 후 복사

다음과 같이 해야 합니다.

this.userProfile = Object.assign({}, this.userProfile, { 
 age: 27, 
 favoriteColor: &#39;Vue Green&#39; 
})
로그인 후 복사

따라서 위의 예는 다음과 같이 변경해야 합니다.

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>vue</title>
 <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script>
 <style>
 li:hover {
  cursor: pointer;
 }
 </style>
</head>
<body>
 <p class="wrap">
 <ul>
  <li v-for="item,index in items" v-on:click="handle(index)">
  <span>{{item.name}}</span>
  <span>{{numbers[index]}}</span>
  </li>
 </ul>
 </p>
 <script>
 var vm = new Vue({
  el: ".wrap",
  data: {
  numbers: [],
  items: [
   {name: &#39;jjj&#39;},
   {name: &#39;kkk&#39;},
   {name: &#39;lll&#39;},
  ]
  },
  methods: {
  handle: function (index) {
   if (typeof(this.numbers[index]) === "undefined" ) {
    this.$set(this.numbers, index, 1);  //(arr,index,newvalue)
   } else {
    this.$set(this.numbers, index, ++this.numbers[index]);
   }
  }
  }
 });
 </script>
</body>
</html>
로그인 후 복사

완료!

1.17 보충 ---------------------------------

"에 대한 이해 방법" 생성된 인스턴스에서는 Vue가 루트 수준 반응 속성을 동적으로 추가할 수 없습니다."?

예:

var vm=new Vue({ 
 el:&#39;#test&#39;, 
 data:{ 
  //data中已经存在info根属性 
  info:{ 
   name:&#39;小明&#39; 
  } 
 } 
}); 
//给info添加一个性别属性 
Vue.set(vm.info,&#39;sex&#39;,&#39;男&#39;);
로그인 후 복사

위의 방법은 올바른 접근 방식이지만 다음을 수행하면 오류가 보고됩니다.

Vue.set(vm.data,&#39;sex&#39;,&#39;男&#39;)
로그인 후 복사

실제로 데이터에 속성을 직접 추가할 수는 없지만 속성을 추가할 수는 있습니다. 데이터의 객체에.

실제로 vm.data는 정의되지 않았습니다.

위 내용은 제가 여러분을 위해 정리한 내용입니다. 앞으로 도움이 되길 바랍니다.

관련 기사:

NodeJS 상위 프로세스 및 하위 프로세스 리소스 공유 원칙 및 구현 방법

Vue에서 휴대폰 번호, 이메일 정기 확인 및 60초 인증 코드 전송의 예

Vue는 활성 클릭 전환 방법을 구현합니다.

위 내용은 Vue가 배열이나 객체의 변경 사항을 감지할 수 없는 문제를 해결하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿