iT邦幫忙

0

axios 下拉式選單連動

  • 分享至 

  • xImage

各位前輩好

程式框架為VUE,運用axios讀取API後端資料繪製圖表。
目標是點取選項後,根據選項變化圖表內容
嘗試使用watch以監聽數據,並觸發相對應處理,但幾經嘗試後皆失敗,想請各位前輩指點問題出於何處?感謝!


json 資料1 (/year)

	{
		"year": 2021,
		"id": 0
	},
	{
		"year": 2022,
		"id": 1
	},
...

json 資料2 (/treemap)

	{
		"id": 0,
		"month": 8,
		"day": 23,
		"use_total_time": 119.2,
		"year": 2021
	},
	{
		"id": 1,
		"month": 7,
		"day": 28,
		"use_total_time": 0.1,
		"year": 2022
	},
    ...

定義html

   <div class="select">
     <select v-model="selectedYear">
       <option
         v-for="item in selectedOneYear"
         :value="item.year"
         :key="item.id"
       >
         {{ item.year }}
       </option>
     </select>
    <v-chart
      class="chart"
      :option="option"
      :update-options="{ notMerge: true }"
    />
</template>

運用axios取得api的資料

  async created() {
    axios.get(config.$api_url + "/treemap").then((response) => {
      this.time1 = response.data.data[0].year; //起始
      this.time2 = response.data.data[response.data.data.length - 1].year; //結束
      axios.get(config.$api_url + "/year").then((response) => {
        this.selectedOneYear = response.data.data;
      });
      axios
        .post(config.$api_url + "/treemap", {
          time1: this.time1,
          time2: this.time2,
        })
        .then((response) => {
          response.data.data.forEach((element) => {
            let set = [
              element.day - 1,
              element.month - 1,
              element.use_total_time,
            ];
            data.push(set);
          });
        });
    });
  },

watch監控取得當前資料(無效)

  watch: {
    selectedYear: {
      handler: function (val) {
        const t2 = this.time2;
        axios
          .post(config.$api_url + "/treemap", { selectedYear: val, time2: t2 })
          .then((response) => {
            this.tableDatasets = response.data.data;
            console.log(response.data.data); //無資料顯示
            data.splice(0, data.length);
            response.data.data.forEach((element) => {
              let set = [
                element.day - 1,
                element.month - 1,
                element.use_total_time,
              ];
              data.push(set);
            })
          });
      },
    },
  },


大致架構

//定義html
<template>
    <div class="select">
      <select v-model="selectedYear">
        <option
          v-for="item in selectedOneYear"
          :value="item.year"
          :key="item.id"
        >
          {{ item.year }}
        </option>
      </select>
    </div>
    <v-chart
      class="chart"
      :option="option"
      :update-options="{ notMerge: true }"
    />
</template>

<script>
import axios from "axios";
import { config } from "../../config.js";

let data = []

export default {
  components: {
    DatePicker,
    VChart,
  },

  data() {
    return {
      time1: "",
      time2: "",
      ...
      option: {
       ...
      },
    };
  },
  
  async created() {
    axios.get(config.$api_url + "/treemap").then((response) => {
      this.time1 = response.data.data[0].year; //起始
      this.time2 = response.data.data[response.data.data.length - 1].year; //結束
      this.allYear = response.data.data;
      axios.get(config.$api_url + "/year").then((response) => {
        this.selectedOneYear = response.data.data;
      });
      axios
        .post(config.$api_url + "/treemap", {
          time1: this.time1,
          time2: this.time2,
        })
        .then((response) => {
          response.data.data.forEach((element) => {
            let set = [
              element.day - 1,
              element.month - 1,
              element.use_total_time,
            ];
            data.push(set);
          });
        });
    });
  },
  watch: {
    selectedYear: {
      handler: function (val) {
        const t2 = this.time2;
        axios
          .post(config.$api_url + "/treemap", { selectedYear: val, time2: t2 })
          .then((response) => {
            this.tableDatasets = response.data.data;
            console.log(response.data.data);//無資料顯示
            data.splice(0, data.length);
            response.data.data.forEach((element) => {
              let set = [
                element.day - 1,
                element.month - 1,
                element.use_total_time,
              ];
              data.push(set);
            });
            */
          });
      },
    },
  },
};
</script>

有將值寫入select選單中,但按了無效。

froce iT邦大師 1 級 ‧ 2023-03-01 14:30:27 檢舉
你 selectedYear 沒在data中?
不是在data中的變數不是響應式變數(ref),自然不能watch。
DanSnow iT邦好手 1 級 ‧ 2023-03-01 17:34:05 檢舉
看了一下 code 有個感想,你都用 async 了為什麼不用 await ,還要用 then ?
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
有隻芫荽
iT邦新手 4 級 ‧ 2023-03-01 15:27:22

我的話會想往以下兩個方向查:

  1. watch 中的 this 是不是你預期中的 this
  2. 有些類型的物件是沒有辦法透過 watch 被 Vue 監聽的:
    • 以陣列索引的方式修改資料
    • 一開始沒有在 data 內註冊的物件

另外,如果要監聽 array 物件,可以試試看把 watch 的設定調整成 deep = true
可以參考:認識 Vue.js watch 監聽器

我要發表回答

立即登入回答