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