我是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>
答案 0 :(得分:2)
计算的属性仅基于内部状态进行计算。它们的特殊之处在于,只要更改它们所依赖的内部状态,就必须重新计算它们。他们不接受任何参数,因为这将使他们更多地依赖于状态的反应性,从而破坏了这种缓存机制。您可以使用计算属性来处理从api获取的数据并对其进行循环,但是现在暂时忽略它。
如注释中所指出,方法的问题是您正在将forEach
循环与一个函数一起使用,并返回内部函数。外部函数不返回任何内容,因此返回值为undefined
。您可以通过多种方法来执行此操作,但是我认为使用Array.prototype.some
最适合您的情况。您向该方法传递一个函数,该函数将针对您要对其调用的数组中的每个项目执行。如果这些调用中的任何一个返回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>
就限定范围的插槽的使用而言,只要this.allMovies
类似于:
[
{
tmdbId: 1
},
{
tmdbId: 2
}
]
请记住,items
插槽会呈现整行,而不仅仅是一个单元格。您将需要用<tr> ... </tr>
包围它。
正如下面的感谢评论所述,如果大量重新渲染模板,则使用此方法可能会导致性能问题。毕竟,每次调用该方法时,它都会针对该数组中的每个项目遍历整个数组。
相反,我们可以使用计算属性来准备数据。由于在挂接的挂钩中只分配一次数据,因此您的计算属性仅应计算一次。当然,您应该避免突变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>