vueChart.js子组件不更新数据

r1wp621o  于 2023-05-17  发布在  Chart.js
关注(0)|答案(1)|浏览(134)

我正在创建一个条形图,显示特定地点的犯罪数据。您可以使用select来选择位置,这将更新位置获取中的经度和纬度。
我循环数据以创建一个包含犯罪类型和每个类别的犯罪数量的对象。然后将这些数据传递给子组件(条形图)以进行显示。但是,当选择一个新位置时,数据似乎不会传递到子组件,因此条形图不会显示任何数据。
我的代码:App.vue

<template>
      <div>
        <h1>Crime Rates in {{selectedLocation}}</h1>
        <BarChartNew v-if="theData" :dataset="theData" :labels="labels" />
    
        <select name="location" @change="getLocation($event, this.locations)" v-model="selectedLocation">
          <option v-for="(coordinates, location) in locations" :key="location" :value="location">
            {{location}}
          </option>
        </select>
      </div>
    </template>
    
    <script>
    import { locations } from "@/middleware/locations.js";
    import BarChartNew from "./components/barChartNew.vue";
    
    export default {
      name: "App",
      components: { BarChartNew },
      data() {
        return {
          crimes: null,
          locations,
          theData: [],
          labels: [],
          selectedLocation: 'Bristol',
          categoryObject: {}
        };
      },
      methods: {
        async fetchData(selectedLocation) {
          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();
            const allCategories = data.map((item) => item.category);
    
            for (let item in data){
              this.categoryObject.hasOwnProperty(data[item].category) 
              ? this.categoryObject[data[item].category]++ 
              : this.categoryObject[data[item].category] = 1
            }
            this.labels.push(...Object.keys(this.categoryObject))
            this.theData = Object.values(this.categoryObject)
          } catch (e) {
            console.error(e);
          }
        },
        getLocation(event){
          const selectedLocation = event.target.value
    
          this.labels = [];
          this.fetchData(event.target.value)
    
    
          return { selectedLocation }
        }
      },
      mounted() {
        this.fetchData(this.selectedLocation);
      },
    }
    </script>

barChartNew.vue:

<template>
<div>
    <Bar
        :data="chartData"
        :options="chartOptions"
    />
    </div>
</template>

<script>
import { Bar } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js'

ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale)

export default {
  components: { Bar },
  props: {
    dataset: {
      type: Array,
      required: false,
    },
    labels: {
      type: Array,
      required: true,
    },
  },
  data() {
    return {
      chartData: {
        labels: this.labels,
        datasets: [
          {
            borderColor: "#f6b09e",
            backgroundColor: "rgb(246, 176, 157)",
            label: "crimes",
            data: this.dataset,
          },
        ],
      },
      chartOptions: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: { display: true },
          title: { display: true, text: "Crimes 🥷🏻 in your area" },
        },
      },
    };
  },
};
</script>
wvmv3b1j

wvmv3b1j1#

子组件中的chartData有两个问题:
1.数据更改时不更新

  1. chart-js要求您重新构建chartData对象和chartData.datasets数组,以检测更改并重新绘制图表
    您可以通过将chartData转换为计算属性来解决这两个问题:
computed: {
    chartData(){
      return {
        labels: this.labels,
        datasets: [
          {
            borderColor: "#f6b09e",
            backgroundColor: "rgb(246, 176, 157)",
            label: "crimes",
            data: this.dataset,
          },
        ],
      }
    }
  }

这里是一个简化的Playground

相关问题