Vue 데이터 가 업데이트 되 었 으 나 페이지 가 업데이트 되 지 않 은 7 가지 상황 집계 및 연장 요약

Vue 에서 강제 업 데 이 트 를 해 야 한 다 는 것 을 알 게 된다 면 99.9%는 어 딘 가 에서 잘못 한 것 이다.
1.Vue 에서 인 스 턴 스 가 생 성 되 었 을 때 data 에 존재 하지 않 는 property 를 검사 할 수 없습니다.
원인:Vue 는 인 스 턴 스 를 초기 화 할 때 property 실행getter/setter으로 전환 되 기 때문에 property 는data대상 에 존재 해 야 Vue 가 응답 식 으로 전환 할 수 있 습 니 다.
필드:

var vm = new Vue({
 data:{},
 //       
 template: '<div>{{message}}</div>'
})
vm.message = 'Hello!' // `vm.message`       
해결 방법:

var vm = new Vue({
 data: {
  //    a、b         
  message: '',
 },
 template: '<div>{{ message }}</div>'
})
vm.message = 'Hello!'
2.Vue 에서 대상 property 의 추가 또는 제거 가 불가능 함
이유:공식-JavaScript(ES5)의 제한 으로 Vue.js 는 대상 속성의 추가 또는 삭 제 를 감지 할 수 없습니다.Vue.js 는 인 스 턴 스 를 초기 화 할 때 속성 을 getter/setter 로 바 꾸 기 때문에 속성 은data대상 에서 만 Vue.js 를 변환 시 켜 야 응답 할 수 있 습 니 다.
필드:

var vm = new Vue({
 data:{
  obj: {
   id: 001
  }
 },
 //       
 template: '<div>{{ obj.message }}</div>'
})

vm.obj.message = 'hello' //       
delete vm.obj.id    //       
해결 방법:

//      - Vue.set
Vue.set(vm.obj, propertyName, newValue)

//      - vm.$set
vm.$set(vm.obj, propertyName, newValue)

//       
//    Object.assign(this.obj, { a: 1, b: 2 })
this.obj = Object.assign({}, this.obj, { a: 1, b: 2 })

//      - Vue.delete
Vue.delete(vm.obj, propertyName)

//      - vm.$delete
vm.$delete(vm.obj, propertyName)
3.Vue 는 배열 색인 을 통 해 배열 항목 을 직접 수정 하 는 것 을 감지 할 수 없습니다.
원인:공식-JavaScript 의 제한 으로 인해 Vue 는 배열 과 대상 의 변 화 를 감지 할 수 없습니다.유 우 계-성능 대가 와 사용자 체험 획득 은 정비례 하지 않 는 다.
필드:

var vm = new Vue({
 data: {
  items: ['a', 'b', 'c']
 }
})
vm.items[1] = 'x' //       
해결 방법:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)

// vm.$set
vm.$set(vm.items, indexOfItem, newValue)

// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
확장:Object.defineProperty()는 배열 의 변 화 를 모니터링 할 수 있 습 니 다.
Object.defineProperty()는 배열 의 변 화 를 모니터링 할 수 있다.그러나 배열 에 속성(index)을 추가 하면 데이터 변 화 를 감지 하지 못 합 니 다.새로 추 가 된 배열 의 아래 표 시 를 감지 할 수 없 기 때문에 속성(index)을 삭제 하 는 것 도 마찬가지 입 니 다.
필드:

var arr = [1, 2, 3, 4]
arr.forEach(function(item, index) {
  Object.defineProperty(arr, index, {
  set: function(value) {
   console.log('   setter')
   item = value
  },
  get: function() {
   console.log('   getter')
   return item
  }
 })
})
arr[1] = '123' //    setter
arr[1]     //    getter      "123"
arr[5] = 5   //      setter   getter
4.Vue 는 배열 의 길 이 를 직접 수정 하 는 변 화 를 모니터링 할 수 없습니다.
원인:공식-JavaScript 의 제한 으로 인해 Vue 는 배열 과 대상 의 변 화 를 감지 할 수 없습니다.유 우 계-성능 대가 와 사용자 체험 획득 은 정비례 하지 않 는 다.
필드:

var vm = new Vue({
 data: {
  items: ['a', 'b', 'c']
 }
})
vm.items.length = 2 //       
해결 방법:

vm.items.splice(newLength)
5.비동기 업데이트 가 실행 되 기 전에 DOM 데 이 터 를 조작 하 는 것 은 변 하지 않 습 니 다.
이유:Vue 는 DOM 을 업데이트 할 때 비동기 로 실 행 됩 니 다.데이터 변 화 를 감지 하면 Vue 는 같은 이벤트 순환 에서 발생 하 는 모든 데이터 변경 을 버퍼 링 합 니 다.같은 watcher 가 여러 번 트리거 되면 대기 열 에 한 번 만 추 가 됩 니 다.버퍼 링 을 할 때 중복 데 이 터 를 제거 하 는 것 은 불필요 한 계산 과 DOM 작업 을 피 하 는 데 매우 중요 하 다.그리고 다음 이벤트 순환"tick"에서 Vue 가 대기 열 을 새로 고치 고 실제(무 거 운 것)작업 을 수행 합 니 다.Vue 는 내부 에서 비동기 대기 열 에 대해 원생Promise.then,MutationObserver,setImmediate을 사용 하려 고 시도 하고 실행 환경 이 지원 되 지 않 으 면setTimeout(fn, 0)으로 대체 합 니 다.
필드:

<div id="example">{{message}}</div>

var vm = new Vue({
 el: '#example',
 data: {
  message: '123'
 }
})
vm.message = 'new message' //     
vm.$el.textContent === 'new message' // false
vm.$el.style.color = 'red' //       
해결 방법:

var vm = new Vue({
 el: '#example',
 data: {
  message: '123'
 }
})
vm.message = 'new message' //     
//   Vue.nextTick(callback) callback    DOM         
Vue.nextTick(function () {
 vm.$el.textContent === 'new message' // true
 vm.$el.style.color = 'red' //         
})
확장:비동기 업데이트 로 인 한 데이터 응답 에 대한 오해

<!--     :    ! -->
<div id="example">{{message.text}}</div>

var vm = new Vue({
 el: '#example',
 data: {
  message: {},
 }
})
vm.$nextTick(function () {
 this.message = {}
 this.message.text = '    !'
})
상단 코드 에서 우 리 는data대상 에서 빈 대상message을 설명 한 다음 에 다음 DOM 업데이트 순환 이 끝 난 후에 발생 하 는 비동기 반전 에서 다음 과 같은 두 단계 코드 를 실 행 했 습 니 다.

this.message = {};
this.message.text = '    !'
여기까지 모드 가 업데이트 되면 페이지 가 마지막 으로 표 시 됩 니 다.
템 플 릿 이 업데이트 되 었 습 니 다.응답 식 특성 이 있어 야 합 니 다.그렇게 생각한다 면 잘못된 곳 으로 들 어 갔 을 것 입 니 다.
처음에 우 리 는data대상 에서 하나의message빈 대상 만 밝 혔 을 뿐text속성 을 가지 지 않 았 기 때문에 이text속성 은 응답 식 특성 을 가지 지 않 았 다.
그러나 템 플 릿 은 확실히 업데이트 되 었 는데,이것 은 또 어떻게 된 일 입 니까?
그것 은 Vue.js 의 DOM 업데이트 가 비동기 적 이기 때 문 입 니 다.즉,setter작업 이 발생 한 후에 명령 이 바로 업데이트 되 지 않 고 명령 의 업데이트 작업 이 지연 되 기 때 문 입 니 다.명령 이 진정 으로 실 행 될 때 이때text속성 이 할당 되 었 기 때문에 명령 이 모델 을 업데이트 할 때 새로운 값 을 얻 을 수 있 습 니 다.
템 플 릿 에 있 는 모든 명령/데이터 바 인 딩 은 해당 하 는 watcher 대상 이 있 고 계산 과정 에서 속성 을 의존 으로 기록 합 니 다.이후 의존 하 는 setter 가 호출 될 때 watcher 재 계산 을 촉발 하고 관련 명령 이 DOM 을 업데이트 할 수 있 습 니 다.

구체 적 인 절 차 는 다음 과 같다.
  • this.dataObj={}을 실행 합 니 다.setter 가 호출 되 었 습 니 다.
  • Vue.js 는 message 가 의존 하 는 setter 가 호출 된 것 을 추적 하면 watcher 재 계산 을 촉발 합 니 다.
  • this.message.text = 'new text'; text 속성 에 값 을 부여 합 니 다.
  • 비동기 리 셋 논리 실행 이 끝나 면 관련 명령 이 DOM 을 업데이트 하고 명령 업데이트 가 실 행 됩 니 다.
  • 따라서 실제 트리거 모드 업데이트 작업 은this.message = {};라 는 문장 으로 인해 발생 한 것 입 니 다.트리거setter가 발생 했 기 때문에 상기 예 를 보면 응답 식 특성 을 가 진 데 이 터 는message층 만 있 고 그의 동적 추가 속성 은 갖 추 지 않 습 니 다.
    위 두 번 째 점-Vue 에 대응 하여 대상 property 의 추가 또는 제거 가 불가능 합 니 다.
    6.순환 플러그 인 이 너무 깊 어서 보기 가 업데이트 되 지 않 습 니까?
    인터넷 에서 어떤 사람들 은 데이터 업데이트 의 등급 이 너무 깊 어서 데이터 가 업데이트 되 지 않 거나 업데이트 가 느 려 서 업데이트 하지 않 으 려 고 한다 고 말한다.
    저 는 이런 상황 을 만난 적 이 없 기 때문에 이런 장면 을 재현 하려 고 하 는 상황 에서 상기 상황 이 발생 하지 않 았 다 는 것 을 알 게 되 었 습 니 다.그래서 이 점 에 대해 너무 많은 묘 사 를 하지 않 았 습 니 다.
    상기 상황 에 대한 해결 방안 은 강제 업 데 이 트 를 사용 하 는 것 이다.
    Vue 에서 강제 업 데 이 트 를 해 야 한 다 는 것 을 알 게 된다 면 99.9%는 어 딘 가 에서 잘못 한 것 이다.
    
    vm.$forceUpdate()
    
    7.확장:루트 매개 변수 가 변 할 때 페이지 가 업데이트 되 지 않 음(데이터 가 업데이트 되 지 않 음)
    경로 의 매개 변수 변화 로 인해 페이지 가 업데이트 되 지 않 는 문 제 를 확대 하고 페이지 가 업데이트 되 지 않 는 것 은 본질 적 으로 데이터 가 업데이트 되 지 않 은 것 이다.
    원인:루트 보기 구성 요소 가 같은 구성 요 소 를 인용 할 때 루트 가 변 할 때 이 구성 요 소 를 업데이트 할 수 없습니다.즉,우리 가 흔히 말 하 는 페이지 가 업데이트 할 수 없 는 문제 입 니 다.
    필드:
    
    <div id="app">
     <ul>
      <li><router-link to="/home/foo">To Foo</router-link></li>  
      <li><router-link to="/home/baz">To Baz</router-link></li>  
      <li><router-link to="/home/bar">To Bar</router-link></li>  
     </ul>  
     <router-view></router-view>
    </div>
    
    const Home = {
     template: `<div>{{message}}</div>`,
     data() {
      return {
       message: this.$route.params.name
      }
     }
    }
    
    const router = new VueRouter({
     mode:'history',
      routes: [
      {path: '/home', component: Home },
      {path: '/home/:name', component: Home }
     ]
    })
    
    new Vue({
     el: '#app',
     router
    })
    상단 코드 에서 우 리 는 루트 구축 옵션routes에 동적 루트'/home/:name'를 설 정 했 습 니 다.루트 구성 요소Home를 함께 사용 합 니 다.이것 은 그들 이 다시 사용 하 는 것 을 의미 합 니 다RouterView.
    경로 전환 을 할 때 페이지 는 첫 번 째 경로 가 일치 하 는 매개 변수 만 렌 더 링 한 다음 에 경로 전환 을 할 때message변화 가 없습니다.
    해결 방법:
    해결 방법 은 여러 가지 가 있 는데,여 기 는 내 가 자주 사용 하 는 몇 가지 방법 만 열거 할 뿐이다.
    감청watch을 통한 변화.
    
    const Home = {
     template: `<div>{{message}}</div>`,
     data() {
      return {
       message: this.$route.params.name
      }
     },
     watch: {
        '$route': function() {
        this.message = this.$route.params.name
      }
      }
    }
    ...
    new Vue({
     el: '#app',
     router
    })
    $route에 귀속<router-view>속성 을 주면 Vue 는 이것 이 다르다 고 생각 합 니 다key.
    단점:<router-view>에서/home등 다른 경로 로 넘 어가 면 우 리 는 구성 요소 업데이트 문 제 를 걱정 하지 않 아 도 되 기 때문에 이때/user속성 은 불필요 하 다.
    
    <div id="app">
     ...
     <router-view :key="key"></router-view>
    </div>
    참고:
    Vue 응답 식 데이터 업데이트 에 대한 오해-https://github.com/xiaofuzi/deep-in-vue/issues/11
    [작은 완자 의 성]-https://www.cnblogs.com/youhong/p/12173354.html
    Vue 데 이 터 를 상세 하 게 업 데 이 트 했 지만 페이지 가 업데이트 되 지 않 은 7 가지 상황 을 모 아 정리 하고 연장 하 는 글 을 소개 합 니 다.더 많은 Vue 데이터 업데이트 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 저 희 를 많이 지 켜 주시 기 바 랍 니 다!

    좋은 웹페이지 즐겨찾기