首页 > 解决方案 > 为什么我得到未定义不是vue js中的对象错误

问题描述

所以我有一个 vue 应用程序,我写在一个由 django 提供的单页 .html 上,由几个组件组成。我现在正在尝试使用 Vue CLI 将这项工作转移到一个真正的 vue.js 项目中,我认为将我的组件从 django .html 页面移动到单个文件 vue 组件中是非常简单的。不幸的是,我的单个文件组件中的几乎每一行都抛出错误(尽管我的整个应用程序及其所有组件都在 .html 中工作),我很难弄清楚这一点。似乎从 vue 组件过渡到单个文件组件需要一些工作。

我得到的当前错误是:

[Vue warn]: Error in render: "TypeError: undefined is not an object (evaluating 'this.milliseconds = parseInt(duration % 1000 / 100)')"

由于我不完全清楚的原因,一旦我使用 vue CLI 移动到单个文件组件 - 每一行都会出错,直到我在每个变量之前添加“this”。我对为什么需要在过滤方法中使用“this”知之甚少,但是当我删除它时,我得到:

[Vue warn]: Error in render: "ReferenceError: Can't find variable: milliseconds"

单个文件组件:

<template>
  <div emptyDiv>
    <h3> Stages </h3>
    <table :style="tableStyle">
      <tbody>
        <template v-for="item in jobs">
          <tr>
            <td v-for="stage_execution in item.stage_execution" :title="stage_execution.exec_node.name" :key="stage_execution.stage.name">
              <b><a :href="item.mongo_link + stage_execution.stage.name + '.txt'" style="color:black">{{ stage_execution.stage.name }}</a></b>
              <br>
              {{ stage_execution.duration_millis | durationReadable  }}
              <br>
              {{ stage_execution.status.name }}
            </td>
          </tr>
        </template>
      </tbody>
    </table>
  </div>
</template>

<script>
import moment from 'moment';

export default {
  data() {
    return {
      jobs: []
    }
  },
  computed: {
    tableStyle() {
      return {
        'background-color': '#f9f9f9',
        'border-color': '#C0C0C0',
        'padding': '8px',
        'width': '100%',
      };
    },
    emptyDiv() {
      return {
        'display': 'contents',
      };
    },
  },
  methods: {
    calculateDuration: function(time_start, time_end) {
      this.theDuration = moment.duration(time_end.diff(time_start))
      if (this.theDuration.seconds() == 0) {
        this.cleanDuration = "N/A"
      }
      else {
        this.cleanDuration = this.theDuration.hours() + " hrs " + this.theDuration.minutes() + " min " + this.theDuration.seconds() + " sec"
      }
      return this.cleanDuration
    }
  },
  filters: {
    durationReadable: function(duration) {
      console.log(parseInt(duration%1000)/100)   //this successfully logs the correct duration
      this.milliseconds = parseInt((duration%1000)/100)
      this.seconds = parseInt((duration/1000)%60)
      this.minutes = parseInt((duration/(1000*60))%60)
      if (this.minutes < 10) {
        this.minutes = '0' + this.minutes
      }
      if (this.seconds < 10){
        this.seconds = '0' + this.seconds
      }
      return this.minutes + " m " + this.seconds + " s " + this.milliseconds + ' ms'
    }
  },
  created() {
    this.binariesEndpoint = 'test.com'
    fetch(this.binariesEndpoint)
    .then(response => response.json())
    .then(body => {
      this.cleanStartTime = moment(body[0].time_start)
      console.log(body[0].time_start)
      this.cleanEndTime = moment(body[0].time_end)
      this.cleanDuration = this.calculateDuration(this.cleanStartTime, this.cleanEndTime)
      this.job_execs.push({
        'name': body[0].job.name,
        'build_id': body[0].build_id,
        'env': body[0].job.env,
        'time_start': this.cleanStartTime.format('LLL'),
        'time_end': this.cleanEndTime.format('LLL'),
        'duration': this.cleanDuration,
      })
    console.log(body[0].job.name)
    })
    .catch( err => {
      console.log('Error Fetching:', this.binariesEndpoint, err);
      return { 'failure': this.binariesEndpoint, 'reason': err };
    })
  },
};
</script>

注意:durationReadable 过滤器中的日志语句正确记录了持续时间。

标签: javascriptvue.js

解决方案


您不能this在过滤器中引用。

过滤器应该是纯函数,而不是依赖于this.

相反,将您的durationReadable函数移动到方法部分。那里可以参考this

然后修改您的模板以使用该方法而不是过滤器:

{{ durationReadable(stage_execution.duration_millis) }}

我希望这有帮助。


推荐阅读