VueJS 从查询参数中添加数据
VueJS Adding data from query parameters
我正在开发一个小型纯客户端 VueJS 应用程序,它使用 VueRouter
在数据输入应用程序时更新 URL,因此用户可以使用 URL刷新页面并在刷新页面时将其数据重新加载到应用程序中。数据存储在查询参数中,例如:
.../app.html#/?time=300&time=300&distance=300&distance=300&unit=m&unit=m
router
根据需要解析数据,但是当我将数据添加到我的空 performance
数组时,标记中的 :class
属性引发
TypeError: Cannot read property 'length' of undefined
其中 undefined
是 performances
数组。通过从应用程序的标记中删除 :class
并成功呈现网站,我已将此问题缩小到 v-for
性能循环内的 :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 文件
...
<div v-for="(performance, index) in performances" :class="{'card-list': performances.length > 1 }">
...
</div>
...
我已阅读 Reactivity in Depth 文档并尝试了以下解决方案:
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
您似乎可能在代码中的某处将其设置为数组以外的其他内容。您将其实例化为一个数组,并且 .length 仅适用于数组和字符串,因此如果您将其设置为对象 json 或其他任何内容,它将出错。 Vue.nextTick 有一个不会将 "this" 带入其中的回调,除非您将其设置为与 Vue.nextTick 函数处于同一范围内的变量。像
var self = this;
//inside nextTick
self.performances.push(performance);
但我认为您不必使用 nextTick,因为 nextTick 在 DOM 重新呈现后更新。 push() 函数将触发 dom 重新呈现,这将使您的页面响应。如果您等待 nextTick,那么在您更改其他内容之前它可能永远不会更新。
<div v-if="performances.length" v-for="(performance, index) in performances"
:class="performances.length > 1 ? 'card-list' : ''">
...
</div>
v-if 属性将确保它在内容存在之前不会呈现。
这应该可以解决您的问题
您还可以执行 {{ performance }} 来找出对象中的确切内容,并且 Google chrome 有一个 vue-debugger 扩展。它向您展示了所有数据属性的实时模型。我会推荐使用它。
我正在开发一个小型纯客户端 VueJS 应用程序,它使用 VueRouter
在数据输入应用程序时更新 URL,因此用户可以使用 URL刷新页面并在刷新页面时将其数据重新加载到应用程序中。数据存储在查询参数中,例如:
.../app.html#/?time=300&time=300&distance=300&distance=300&unit=m&unit=m
router
根据需要解析数据,但是当我将数据添加到我的空 performance
数组时,标记中的 :class
属性引发
TypeError: Cannot read property 'length' of undefined
其中 undefined
是 performances
数组。通过从应用程序的标记中删除 :class
并成功呈现网站,我已将此问题缩小到 v-for
性能循环内的 :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 文件
...
<div v-for="(performance, index) in performances" :class="{'card-list': performances.length > 1 }">
...
</div>
...
我已阅读 Reactivity in Depth 文档并尝试了以下解决方案:
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
您似乎可能在代码中的某处将其设置为数组以外的其他内容。您将其实例化为一个数组,并且 .length 仅适用于数组和字符串,因此如果您将其设置为对象 json 或其他任何内容,它将出错。 Vue.nextTick 有一个不会将 "this" 带入其中的回调,除非您将其设置为与 Vue.nextTick 函数处于同一范围内的变量。像
var self = this;
//inside nextTick
self.performances.push(performance);
但我认为您不必使用 nextTick,因为 nextTick 在 DOM 重新呈现后更新。 push() 函数将触发 dom 重新呈现,这将使您的页面响应。如果您等待 nextTick,那么在您更改其他内容之前它可能永远不会更新。
<div v-if="performances.length" v-for="(performance, index) in performances"
:class="performances.length > 1 ? 'card-list' : ''">
...
</div>
v-if 属性将确保它在内容存在之前不会呈现。
这应该可以解决您的问题
您还可以执行 {{ performance }} 来找出对象中的确切内容,并且 Google chrome 有一个 vue-debugger 扩展。它向您展示了所有数据属性的实时模型。我会推荐使用它。