【问题标题】:VueJS lifecycle after submit form提交表单后的 VueJS 生命周期
【发布时间】:2021-04-13 04:12:47
【问题描述】:

在执行 API 调用以获取一些数据后,我想在 vuejs 中绘制一些 d3js 字符。为此,我创建了一个表单,其输入用于从 API 收集数据。提交表单后,我会调用我的 d3js 函数来根据检索到的数据绘制图表。我希望仅在数据不为空时调用绘图函数。为此,我使用了基于数据长度的条件渲染 v-if。到目前为止,一切都很好。我的问题是,如果我在表单中输入任何内容,一旦绘制了图,就会创建一个新图,就好像每次 if 语句被一次又一次地评估一样,我不知道它是否与生命周期有关,但是如何避免这种行为呢?

<template>
  <meta charset="utf-8">
  <h4>Associate Information</h4>
        
          <form @submit.prevent="onSubmit">
            <input placeholder="Associate Id" v-model="associateId" /> <br />
            <input placeholder="Starting date" v-model="initialDate" /> <br />
            <input placeholder="Ending date" v-model="finalDate" /> <br />
            <button v-on:click="getAssociatesbyIdAndDates()">submit</button>
          </form>
        
  

  <div class="chart" v-if="dailyData.length">
          {{ DailyBillabilityLinePlot() }}
          {{ WeeklyMonthlyQuarterlyBarPlot(weeklyData) }}
  </div>
  
  <div class="linePlot"></div>
  <div class="barPlot" v-if="weeklyData.length">
    
    <button v-on:click="WeeklyMonthlyQuarterlyBarPlot(weeklyData)">Weekly</button>
    <button v-on:click="WeeklyMonthlyQuarterlyBarPlot(monthlyData)">Monthly</button>
    <svg id="chart" viewBox="0 0 960 300"></svg>
    
  </div>
</template>

<script>
import * as d3 from 'd3'
export default {
  name: 'Timecard',
  props: {
    msg: String
  },

  data() {
    return {
      apiUrl: "",
      myNumber: 0,
      environment: "",
      apiTst:"",
      name:"",
      initialDate: "",
      finalDate: "",
      associateId: "",
      dailyData: [],
      weeklyData:[],
      monthlyData:[],
    }
  },
methods: {
  WeeklyMonthlyQuarterlyBarPlot(data){
  // plot a d3 bar plot
      
 },
  DailyBillabilityLinePlot() { // plot another d3 line plot}
  getAssociatesbyIdAndDates() {
      // Connect to the backend and get the list of associates
      // http://localhost:8080/timecards/period/test/274/2020-04-14/2020-04-22
      console.log("Fetching the data for an associates from the backend based on initial date and final date...");
      this.axios.get(this.apiUrl + "test/period/test/" + this.associateId + "/" + this.initialDate + "/" + this.finalDate)
        .then(response => {
            this.dailyData = response.data;
            console.log(response.status);
        })
        .catch(error => {
          console.error(error);
        })

      this.axios.get(this.apiUrl + "test/weekly/" + this.associateId + "/" + this.initialDate + "/" + this.finalDate)
        .then(response => {
            this.weeklyData = response.data;
            console.log(response.status);
        })
        .catch(error => {
          console.error(error);
        })

      this.axios.get(this.apiUrl + "test/monthly/" + this.associateId + "/" + this.initialDate + "/" + this.finalDate)
        .then(response => {
            this.monthlyData = response.data;
            console.log(response.status);
        })
        .catch(error => {
          console.error(error);
        })
    },}
  onSubmit() {
      let consultantApi = {
       name: this.name,
       initialDate: this.initialDate,
       finalDate: this.finalDate,
     }
     this.$emit('consultantApi-submitted', consultantApi)

     this.name = ''
     this.initialDate = ''
     this.finalDate = ''
    }
  },
  mounted: function() {
    this.apiUrl = process.env.VUE_APP_BACKEND_API;
    this.environment = process.env.NODE_ENV;
  }  

初始形式

提交完整表格后的 D3 绘图

每当我按下表格中的任何键时,都会创建新的 d3 绘图

【问题讨论】:

  • 您是否需要表单在提交后保持可见,以便用户输入新信息?或者表单提交后会消失吗?
  • 这是一个选项,但我希望用户可以创建一个新的提交来查看其他日期的可计费性。
  • 你能显示设置weeklyData的代码吗?
  • 完成,在 getAssociatesbyIdAndDates() 中
  • 每次调用 update() 时都会创建您的 plotGroup 元素。创建一次并在 update() 中更新其内容

标签: forms d3.js vuejs3


【解决方案1】:

是的,这是因为更新任何模型都会重新渲染整个组件。

为了解决这个问题,我发现最简单的方法是将图表放入另一个组件中,以便保护重新渲染。

示例:

var app = Vue.createApp({
  data() {
    return {
      abc: 'ABC',
      list: [1, 2, 3]
    };
  }
});

app.component("my-chart", {
  template: `<div >{{Math.random()}}</div>`
});

app.mount("#app");
<script src="https://unpkg.com/vue@3.0.6/dist/vue.global.prod.js"></script>
<div id="app">
  <input v-model="abc" />
  <div v-if="list.length">
    {{Math.random()}}
  </div>
  <my-chart></my-chart>
</div>

【讨论】:

  • 嘿丹尼尔,我不确定你想给我看什么。每次我在表单中添加或删除一个字母时,都会生成一个新的随机值。这正是我想要避免的。我希望仅在单击提交按钮时才生成一个值。你认为你可以更新你的例子吗?无论如何,谢谢你的回答。
  • 有两个数字,第一个是与数据同一个组件的一部分,随着输入的变化而变化,第二个在另一个组件内部,不会改变
【解决方案2】:

我认为您的错误在父组件中。我会尝试检查它多久发出一次consultApi。您的表单似乎一直在提交输入更改事件而不是提交表单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 2018-04-28
    • 2017-08-04
    • 1970-01-01
    • 2021-11-24
    • 2018-09-30
    • 1970-01-01
    相关资源
    最近更新 更多