【问题标题】:Vue.js: A value in a v-for loop is not staying with the correct array itemsVue.js:v-for 循环中的值未与正确的数组项保持一致
【发布时间】:2019-07-02 12:28:21
【问题描述】:

我正在尝试创建一个简单的应用程序来为服务部门申请车钥匙。显然代码可以写得更好,但这是我使用 Vue.js 的第三天。代码中第一个 p 标签中调用的时间函数每分钟更新一次,以记录经过的时间。我遇到的问题是,当我请求一个新键时,时间函数没有按照预期遵循数组项。例如,如果没有其他请求,我提交的第一个请求可以完美运行。但是,当我提交一个新请求时,从我的第一个请求到我的第二个请求所经过的时间。我确信这可能与粘合在一起的代码有关,但我已经尝试了我能想到的一切。任何帮助将不胜感激。

<template>
    <div class="row">
        <div class="card col-md-6" v-for="(key, index) in keys" :key="index">
          <div class="card-body">
            <h5 class="card-title">Service Tag: {{ key.service_tag }}</h5>
            <p class="card-text"> {{time}} {{key.reqTimestamp}}min</p>
            <p class="invisible">{{ start(key.reqTimestamp) }}</p>
            <p class="card-text">Associates Name: {{key.requestor_name}}</p>
            <p class="card-text">Model: {{key.model}}</p>
            <p class="card-text">Color: {{key.color}}</p>
            <p class="card-text">Year: {{key.year}}</p>
            <p class="card-text">Comments: {{key.comments}}</p>
            <p class="card-text">Valet: {{key.valet}}</p>
            <input class="form-control" v-model="key.valet" placeholder="Name of the person getting the car...">
            <button
              @click="claimedKey(key.id, key.valet)"
              type="submit" 
              class="btn btn-primary"
              >Claim</button>
              <button v-if="key.valet !== 'Unclaimed'"
              @click="unclaimedKey(key.id, key.valet)"
              type="submit" 
              class="btn btn-primary"
              >Unclaim</button>
            <button class="btn btn-success" @click="complete(key.id)">Complete</button>
          </div>
      </div>
<!-- END OF CARD -->
<!-- START OF FORM -->
      <div class="row justify-content-md-center request">
        <div class="col-md-auto">
          <h1 class="display-4">Operation Tiger Teeth</h1>
          <form class="form-inline" @submit="newKey(service_tag, requestor_name, comments, model, year, color, valet, reqTimestamp)">
            <div class="form-group col-md-6">
              <label for="service_tag">Service Tag: </label>
              <input class="form-control form-control-lg" v-model="service_tag" placeholder="ex: TB1234">
            </div>
            <div class="form-group col-md-6">
              <label for="service_tag">Associates Name: </label>
              <!-- <input class="form-control form-control-lg" v-model="requestor_name" placeholder="Your name goes here..."> -->
              <div class="form-group">
                <label for="exampleFormControlSelect1">Example select</label>
                <select v-model="requestor_name" class="form-control" id="requestor_name">
                  <option>James Shiflett</option>
                  <option>Austin Hughes</option>
                </select>
              </div>
            </div>
            <div class="form-group col-md-6">
              <label for="service_tag">Model: </label>
              <input class="form-control form-control-lg" v-model="model" placeholder="What is the model of the vehicle?">
            </div>
            <div class="form-group col-md-6">
              <label for="service_tag">Color: </label>
              <input class="form-control form-control-lg" v-model="color" placeholder="What is the color of the vehicle?">
            </div>
            <div class="form-group col-md-6">
              <label for="service_tag">Year: </label>
              <input class="form-control form-control-lg" v-model="year" placeholder="What year is the car?">
            </div>
            <div class="form-group col-md-6">
              <label for="service_tag">Comments: </label>
              <input class="form-control form-control-lg" v-model="comments" placeholder="Place any additional comments here...">
            </div>
            <div class="form-group col-md-6 invisible">
              <label for="service_tag">Valet: </label>
              <input v-model="valet">
            </div>
            <div class="form-group col-md-6 invisible">
              <label for="service_tag">Timestamp: </label>
              <input v-model="reqTimestamp">
            </div>
            <div class="col-md-12">
              <button class="btn btn-outline-primary" type="submit">Request A Key</button>
            </div>
          </form>
        </div>
      </div>
    </div>
</template>

<script>
import { db } from "../main";
import { setInterval } from 'timers';
export default {
  name: "HelloWorld",
  data() {
    return {
      keys: [],
      reqTimestamp: this.newDate(),
      service_tag: "",
      requestor_name: "",
      comments: "",
      color: "",
      model: "",
      year: "",
      inputValet: true,
      valet: "Unclaimed",
      state: "started",
      startTime: '',
      currentTime: Date.now(),
      interval: null,
    };
  },
  firestore() {
    return {
      keys: db.collection("keyRequests").where("completion", "==", "Incomplete")
    };
  },
  methods: {
    newKey(service_tag, requestor_name, comments, model, year, color, valet, reqTimestamp, completion) {
      // <-- and here
      db.collection("keyRequests").add({
        service_tag,
        requestor_name,
        comments,
        color,
        model,
        year,
        valet,
        reqTimestamp,
        completion: "Incomplete",
      });
      this.service_tag = "";
      this.requestor_name = "";
      this.comments = "";
      this.color = "";
      this.model = "";
      this.year = "";
      this.reqTimestamp = this.newDate()
    },
      complete(id) {
        db.collection("keyRequests").doc(id).update({
          completion: "Complete"
        })
      },
    // deleteKey(id) {
    //   db.collection("keyRequests")
    //     .doc(id)
    //     .delete();
    claimedKey(id, valet) {
      console.log(id);
      this.inputValet = false
      db.collection("keyRequests").doc(id).update({
        valet: valet,
        claimTimestamp: new Date()
      })
    },
    moment: function () {
    return moment();
    },
    newDate () {
      var today = new Date()
      return today
    },
    updateCurrentTime: function() {
      if (this.$data.state == "started") {
          this.currentTime = Date.now();
        }
      },
      start(timestamp) {
        return this.startTime = timestamp.seconds * 1000
      }      
    },
  mounted: function () {
            this.interval = setInterval(this.updateCurrentTime, 1000);
  },
  destroyed: function() {
            clearInterval(this.interval)
  },
  computed: {
    time: function() {
      return Math.floor((this.currentTime - this.startTime) /60000);
    }
  }
  }
</script>

理想情况下,我正在寻找遵循每个请求的时间间隔。

【问题讨论】:

  • “时间函数没有按照预期的方式跟随数组项”---你能详细说明这是关于代码的哪一部分吗?
  • 基本上,我从未见过 keys:[] 被更改。所以......就是这样。
  • 我想要做的是在段落标记中调用计算时间属性,以便在该循环迭代中坚持数组元素。这样,正确的经过时间就可以使用正确的数据。
  • keys 数组是我在数据库(firestore)中调用的位置
  • 我没有看到 firestore 方法被调用

标签: javascript arrays vue.js vuejs2 v-for


【解决方案1】:

所以模板中的问题行是:

<p class="card-text"> {{time}} {{key.reqTimestamp}}min</p>
<p class="invisible">{{ start(key.reqTimestamp) }}</p>

start 的调用有副作用,这是渲染组件的主要禁忌。在这种情况下,它会更改startTime 的值,从而导致time 发生更改。我有点惊讶这没有触发无限渲染递归警告......

相反,我们应该只使用当前迭代项的相关数据,您称之为key。我将介绍一种计算给定 key 的经过时间的方法:

methods: {
  elapsedTime (key) {
    const timestamp = key.reqTimestamp;
    const startTime = timestamp.seconds * 1000;

    return Math.floor((this.currentTime - startTime) / 60000);
  }
}

您会注意到这结合了函数starttime 的各个方面。重要的是它不会修改 this 上的任何内容。

然后你可以在你的模板中调用它:

<p class="card-text"> {{elapsedTime(key)}} {{key.reqTimestamp}}min</p>

【讨论】:

  • 工作就像一个魅力。非常感谢您的帮助和解释我哪里出错了!
  • 所以我只是将它托管在 github.io 上以快速测试,当请求在一台设备上提交时,时间戳是正确的。当您在另一台设备(我的手机)上查看该请求时,时间戳显示为 -13 分钟。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 2015-09-22
  • 1970-01-01
  • 1970-01-01
  • 2021-05-23
  • 1970-01-01
  • 2018-06-02
相关资源
最近更新 更多