Vue Chart.js子组件切换地点后数据不更新求助
问题:切换地点后柱状图无数据更新
问题根源
- 父组件数据未重置:切换地点时,
categoryObject未清空,新数据会与旧数据累加,导致传递给子组件的labels和dataset包含重复或错误内容。 - 子组件未同步props变化:
chartData仅在组件初始化时读取一次props值,后续props更新时不会自动同步,图表数据无法更新。
修复方案
1. 修复父组件(App.vue)
修改fetchData方法,每次请求新数据前重置相关变量,同时优化数组遍历方式:
async fetchData(selectedLocation) { // 重置数据容器,避免旧数据累加 this.categoryObject = {}; this.labels = []; this.theData = []; const lat = this.locations[selectedLocation].lat const lng = this.locations[selectedLocation].lng try { const response = await fetch( `https://data.police.uk/api/crimes-street/all-crime?lat=${lat}&lng=${lng}&date=2023-01`, { "Content-Type": "text/plain", } ); const data = await response.json(); // 用of遍历数组元素,而非in遍历索引 for (let item of data){ this.categoryObject.hasOwnProperty(item.category) ? this.categoryObject[item.category]++ : this.categoryObject[item.category] = 1 } // 直接赋值替换数组,避免push导致重复 this.labels = Object.keys(this.categoryObject) this.theData = Object.values(this.categoryObject) } catch (e) { console.error(e); } }
简化getLocation方法(移除重复的labels重置):
getLocation(event){ const selectedLocation = event.target.value this.fetchData(selectedLocation) }
2. 修复子组件(barChartNew.vue)
将chartData改为计算属性,实现props与图表数据的自动同步:
export default { components: { Bar }, props: { dataset: { type: Array, required: false, default: () => [] // 添加默认值避免空值报错 }, labels: { type: Array, required: true, }, }, computed: { chartData() { return { labels: this.labels, datasets: [ { borderColor: "#f6b09e", backgroundColor: "rgb(246, 176, 157)", label: "crimes", data: this.dataset, }, ], } } }, data() { return { chartOptions: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: true }, title: { display: true, text: "Crimes 🥷🏻 in your area" }, }, }, }; }, };
额外优化
利用v-model的特性,直接监听selectedLocation变化触发数据请求,无需绑定@change事件:
<!-- 移除@change绑定 --> <select name="location" v-model="selectedLocation"> <option v-for="(coordinates, location) in locations" :key="location" :value="location"> {{location}} </option> </select>
添加watch监听:
watch: { selectedLocation(newVal) { this.fetchData(newVal) } }
内容的提问来源于stack exchange,提问作者bm17
相关产品推荐
相关产品推荐

