Javascript vue.js方法返回保持更新

Javascript vue.js方法返回保持更新,javascript,vue.js,Javascript,Vue.js,我是Vue js的新手,很抱歉这个愚蠢的问题。我使用一个v-data-table在数组中循环。我需要方法的返回值不改变,但是当方法运行时,每一行的返回值都会改变 我尝试了一个计算值,但由于某种原因,您无法将变量传递到计算字段 <template> <div> <v-data-table :items="responseData" class="elevation-1" > <template slo

我是Vue js的新手,很抱歉这个愚蠢的问题。我使用一个v-data-table在数组中循环。我需要方法的返回值不改变,但是当方法运行时,每一行的返回值都会改变

我尝试了一个计算值,但由于某种原因,您无法将变量传递到计算字段

<template>
  <div>
    <v-data-table
      :items="responseData"
      class="elevation-1"
    >
      <template slot="items" slot-scope="props">
        <td :key="props.item.tmdbId" class="text-xs-right">
          This: {{checkMovieExists(props.item.tmdbId)}}
        </td>
      </template>
    </v-data-table>
  </div>
</template>

<script>
import axios from "axios";
export default {
  data() {
    return {
      allMovies: []
    };
  },
  mounted() {
    axios.get("XXXX")
      .then(response => (this.allMovies = response.data)) 
  },
  methods: {
    checkMovieExists(strMovieTmdbId){
      this.allMovies.forEach(movie => {
        if (movie.tmdbId == strMovieTmdbId) {
          return "Exists"
        }
      });                
    }
  }
}
</script>

此:{{checkMovieExists(props.item.tmdbId)}
从“axios”导入axios;
导出默认值{
数据(){
返回{
所有电影:[]
};
},
安装的(){
axios.get(“XXXX”)
.然后(response=>(this.allMovies=response.data))
},
方法:{
checkMovieExists(strMovieTmdbId){
this.allMovies.forEach(movie=>{
if(movie.tmdbId==strMovieTmdbId){
返回“存在”
}
});                
}
}
}

计算属性仅基于内部状态计算。它们的特殊之处在于,只要它们所依赖的内部状态发生变化,就必须重新计算它们。它们不接受任何参数,因为这会使它们依赖于您的状态的更多反应,从而破坏这种缓存机制。您可以使用computed属性来处理从api获得的数据,并在其上进行循环,但是现在让我们忽略它

正如注释中指出的,您的方法的问题在于,您正在使用带有函数的
forEach
循环,并在内部函数中返回。外部函数不返回任何内容,因此返回值为
未定义
。有几种方法可以做到这一点,但我认为在您的情况下使用效果最好。您向该方法传递一个函数,该函数将对调用它的数组中的每个项执行。如果这些调用中的任何一个返回
true
,则整个事件将返回
true
,否则它将返回
false

movieExists(strMovieTmdbId){
  return this.allMovies.some(movie => movie.tmdbId === strMovieTmdbId);
}
您会注意到,我在这里返回一个布尔值。之所以这样做,是因为您的函数被称为
XYZExists
。我们可以使用此布尔响应在模板中输出适当的内容

  <template slot="items" slot-scope="props">
    <td :key="props.item.tmdbId" class="text-xs-right">
      This: {{ checkMovieExists(props.item.tmdbId) ? 'Exists' : '' }}
    </td>
  </template>
请记住,
items
槽将呈现整行,而不仅仅是一个单元格。您需要用
将其包围起来


正如thanksd在下面所评论的,如果模板被多次重新引用,使用此方法可能会导致性能问题。毕竟,每次调用该方法时,它都会查看整个数组,查看该数组中的每个项

相反,我们可以使用计算属性准备数据。因为在挂载的钩子中只分配一次数据,所以计算的属性应该只计算一次。当然,您应该避免对this.allMovies进行变异,以防止重新计算您的计算属性

您可以保留我们之前创建的方法,但我们将使用此方法来计算数据,而不是使用
this.allMovies
来渲染数据。。。一旦我们使用映射来创建包含方法结果的额外属性

computed: {
  preparedData () {
    return this.responseData.map(
      row => {
        return {
          ...row,
          exists: this.movieExists(row.tmdbId)
        }
      }
    );
  }
}
现在,我们不再使用
responseData
(不管是什么),而是使用
preparedData
来呈现表格。由于我们现在在每一行上都有一个预先计算的属性
exists
,因此我们可以只检查
props.item.exists
,而不必调用函数。重新提交模板时,只要
responseData
保持不变,我们就使用
preparedData
的缓存版本

<v-data-table
  :items="preparedData"
  class="elevation-1"
>
  <template slot="items" slot-scope="props">
    <td :key="props.item.tmdbId" class="text-xs-right">
      This: {{ props.item.exists ? 'Exists' : '' }}
    </td>
  </template>
</v-data-table>

此:{{props.item.exists?'exists':''}

计算属性仅基于内部状态计算。它们的特殊之处在于,只要它们所依赖的内部状态发生变化,就必须重新计算它们。它们不接受任何参数,因为这会使它们依赖于您的状态的更多反应,从而破坏这种缓存机制。您可以使用computed属性来处理从api获得的数据,并在其上进行循环,但是现在让我们忽略它

正如注释中指出的,您的方法的问题在于,您正在使用带有函数的
forEach
循环,并在内部函数中返回。外部函数不返回任何内容,因此返回值为
未定义
。有几种方法可以做到这一点,但我认为在您的情况下使用效果最好。您向该方法传递一个函数,该函数将对调用它的数组中的每个项执行。如果这些调用中的任何一个返回
true
,则整个事件将返回
true
,否则它将返回
false

movieExists(strMovieTmdbId){
  return this.allMovies.some(movie => movie.tmdbId === strMovieTmdbId);
}
您会注意到,我在这里返回一个布尔值。之所以这样做,是因为您的函数被称为
XYZExists
。我们可以使用此布尔响应在模板中输出适当的内容

  <template slot="items" slot-scope="props">
    <td :key="props.item.tmdbId" class="text-xs-right">
      This: {{ checkMovieExists(props.item.tmdbId) ? 'Exists' : '' }}
    </td>
  </template>
请记住,
items
槽将呈现整行,而不仅仅是一个单元格。您需要用
将其包围起来


正如thanksd在下面所评论的,如果模板被多次重新引用,使用此方法可能会导致性能问题。毕竟,每次调用该方法时,它都会查看整个数组,查看该数组中的每个项

相反,我们可以使用计算属性准备数据。因为在挂载的钩子中只分配一次数据,所以计算的属性应该只计算一次。当然,您应该避免对this.allMovies进行变异,以防止重新计算您的计算属性

您可以保留我们之前创建的方法,但我们将使用此方法来计算数据,而不是使用
this.allMovies
来渲染数据。。。一旦我们使用映射来创建包含方法结果的额外属性

computed: {
  preparedData () {
    return this.responseData.map(
      row => {
        return {
          ...row,
          exists: this.movieExists(row.tmdbId)
        }
      }
    );
  }
}
现在,我们不再使用
responseData
(不管是什么),而是使用
preparedData
来呈现表格。因为我们现在有一个预先计算的pr