2016-12-21 13 views
2

데이터를 응용 프로그램에 입력 할 때 VueRouter을 사용하는 작은 클라이언트 쪽 VueJS 응용 프로그램에서 작업 중이므로 사용자는 URL을 사용하여 페이지를 새로 고치고 데이터를 다시로드 할 수 있습니다 페이지를 새로 고칠 때 앱에 데이터는 router의 필요에 따라 데이터 구문 분석 : .../app.html#/?time=300&time=300&distance=300&distance=300&unit=m&unit=m VueJS 쿼리 매개 변수의 데이터 추가

, 쿼리 매개 변수에 전 저장,하지만 난 내 빈 performance 배열에 데이터를 추가 할 때, 내 마크 업에 :class 속성은

를 제기한다

TypeError: Cannot read property 'length' of undefined

여기서 undefinedperformances 어레이입니다. 이 문제를 v-for 성능 루프 내의 :class 속성으로 좁히고 응용 프로그램의 마크 업에서 :class을 제거하고 사이트를 성공적으로 렌더링했습니다. 나는 performances 데이터 배열이 :class으로 전달되지 않았을 것으로 추측합니다.

VueRouter 설명서에이 유형의 라우팅에 대한 언급이 없습니다. URL 쿼리 매개 변수에서 응용 프로그램으로 데이터를 전달하는 방법은 무엇입니까?

// js file 
var router = new VueRouter({}); // empty because no routes, just query parameters, so no need for list 

var app = new Vue({ 
    el: '#app', 
    data: function() { 
     return { 
      performances: [], 
      units: units, 
      newPerformance: { 
       distance: { 
        value: '', 
        units: units.distance.options[0] 
       }, 
       time: { 
        formatted: '', 
        value: '' 
       }, 
      }, 
      editingPerformance: null, 
     } 
    }, 
    router: router, 
    watch: { 
     performances: { 
      handler: function() { 
       this.drawChart(); 
       this.updateURL(); 
      }, 
      deep: true 
     } 
    }, 
    updateURL: function() { 
     var times = this.performances.map(function(v) { 
       return v.time.value 
      }), 
      distances = this.performances.map(function(v) { 
       return v.distance.value 
      }), 
      units = this.performances.map(function(v) { 
       return v.distance.units.value 
      }); 
     router.push({ 
      query: { 
       time: times, 
       distance: distances, 
       dunit: units 
      } 
     }); 
    } 
    .... 
}); 

HTML 파일 나는 Reactivity in Depth 문서를 읽어와 같은 솔루션을 시도

... 
<div v-for="(performance, index) in performances" :class="{'card-list': performances.length > 1 }"> 
... 
</div> 
... 

: Vue.nextTick(function() { this.performances.push(performance); })

다음 (간결하게하기 위해 응축) 내 관련 코드입니다

Vue.set(app, 'performances',performanceArray);

같은 오류가 발생합니다. 요청시 더 많은 코드를 제공 할 수 있습니다.

편집 : 추가 스택 추적 :

[Vue warn]: Error when rendering root instance: warn @ vue.js:513 
Vue._render @ vue.js:2934 
(anonymous function) @ vue.js:2335 
get @ vue.js:1643run @ vue.js:1712 
flushSchedulerQueue @ vue.js:1530 
(anonymous function) @ vue.js:465 
nextTickHandler @ vue.js:414 

가 바로 뒤에 : 당신은 당신의 코드에서 어딘가에 배열 이외로 설정 될 수있다처럼

vue.js:427 TypeError: Cannot read property 'length' of undefined(…) 
logError @ vue.js:427 
+0

구성 요소를 만들고 앱에서 해당 메소드를 만들지 말고 포함시키는 것이 좋습니다. –

답변

2

보인다. 배열로 인스턴스화하고 .length는 배열과 문자열에서만 작동하므로 객체, json 또는 다른 것으로 설정하면 오류가 발생합니다. Vue.nextTick 함수는 Vue.nextTick 함수와 같은 범위에 변수를 설정하지 않는 이상 "this"를 전달하지 않는 콜백을 가지고 있습니다.

var self = this; 

//inside nextTick 

self.performances.push(performance); 

하지만 난 당신이 DOM 후 nextTick 업데이트가 다시 렌더링되어 있기 때문에 nextTick를 사용할 필요가 없습니다 상상할 것 같은. push() 함수는 DOM 재 렌더링을 트리거하여 페이지를 반응 적으로 만듭니다. nextTick을 기다리면 다른 것을 바꿀 때까지 업데이트되지 않을 수 있습니다.

<div v-if="performances.length" v-for="(performance, index) in performances" 
:class="performances.length > 1 ? 'card-list' : ''"> 
... 
</div> 

v-if 속성은 콘텐츠가있을 때까지 렌더링되지 않도록합니다.당신도 할 수

문제가 해결됩니다

{{성능}} 객체에 정확하게, 구글 크롬은 VUE 디버거 확장명이 무엇인지 찾습니다. 모든 데이터 속성의 라이브 모델을 보여줍니다. 나는 그것을 사용하는 것이 좋습니다.

+0

다른 문제가 있음이 밝혀졌습니다. (물론 간과 한) 다른 줄에는 label이 정의되어 있지 않은 줄': class = "{ 'hide': performance.label.length === 0, ...}'이 있습니다. 내 라우터. 일단 그것을 밖으로 가져 가면 내 코드가 예상대로 작동했다. 올바른 배열로 내 성능에 대한 올바른 대답을했기 때문에 나는'performances' 배열을 배열이 아닌 다른 것으로 설정했다. 방금이 문제가 해결되었는지 확인했습니다. 도와 주셔서 감사합니다. – DFenstermacher

+0

절대적으로 감사합니다! –