在 vuejs 中使用 v-for 时无限重复
Posted
技术标签:
【中文标题】在 vuejs 中使用 v-for 时无限重复【英文标题】:Infinite repeated while using v-for in vuejs 【发布时间】:2021-10-05 04:41:33 【问题描述】:我有一个获取书籍列表的 API,在每本书中我都有作者 ID。 我还想通过另一个 API(获取作者)从该 ID 获取作者姓名,所以我使用 v-for 来获取书籍列表中的项目。我调用 getAuthor(authorId) 函数的每个项目,但它会无限重复。有谁知道是什么原因? 我的源代码:
export default
name: 'GetBooks',
data()
return
books: [],
categories: [],
author: [],
;
,
created()
this.getBooks();
,
methods:
getBooks()
BookServices.getBooks().then(response =>
this.books = response.data;
console.log(response.data);
)
.catch(e =>
console.log(e);
);
,
getAuthor(id)
BookServices.getAuthor(id).then(response =>
this.author = response.data.name;
console.log(response.data.name);
);
return this.author;
,
与:
<tbody>
<tr v-for="item in books" :key="item.id">
<td> item.id </td>
<td> item.name </td>
<td> getAuthor(item.authorId) </td>
<td> item.price </td>
<td> item.year </td>
<td><input class='myclass' type='button' value='Detail'/></td>
</tr>
</tbody>
【问题讨论】:
【参考方案1】:问题是每次调用getAuthor
都会触发一次模板重新渲染,这反过来又会触发对getAuthor
的新调用,从而导致无限调用。
我能想到两种解决方案:
-
在
td
上使用 v-once
指令。该指令防止在初始渲染后进一步更新元素。
<td v-once> getAuthor(item.authorId) </td>
在获取图书数据时填充作者(也可以在 API 中完成)。
getBooks()
BookServices.getBooks().then(response =>
this.books = response.data;
this.books = this.books.map(book =>
book["author"] = this.getAuthor(book.authorId)
return book
)
)
.catch(e =>
console.log(e);
);
,
然后,在模板中引用作者:
<tr v-for="item in books" :key="item.id">
<td> item.id </td>
<td> item.name </td>
<td> item.author </td>
<td> item.price </td>
<td> item.year </td>
<td><input class='myclass' type='button' value='Detail'/></td>
</tr>
【讨论】:
非常感谢!正如你所说,每次调用 getAuthor 都会触发一次模板重新渲染,这就是它有无限调用的原因。非常感谢@IgorMoraru【参考方案2】:模型获取方法应该决定何时以及如何获取作者,而不是标记。 (这是@IgorMoraru 的第二个好主意,已更正以正确处理作者的异步获取)。
这也修复了将书籍作者分配给视图实例的 OP 代码错误。
getBooks()
BookServices.getBooks().then(response =>
this.books = response.data;
console.log(response.data);
this.getAuthors();
)
.catch(e =>
console.log(e);
);
,
getAuthors()
let promises = this.books.map(book => this.getAuthor(book));
return Promise.all(promises);
,
getAuthor(book) // note the change: pass the book here, not the id
BookServices.getAuthor(book.id).then(response =>
book.author = response.data.name;
console.log(response.data.name);
);
return this.author;
,
保护(暂时)缺少作者的书籍的标记...
<td> item.id </td>
<td> item.name </td>
<td v-if="item.author"> item.author </td>
<td v-else>fetching...</td>
<td> item.price </td>
<td> item.year </td>
【讨论】:
您的解决方案对我帮助很大!我成功修复了?@danh以上是关于在 vuejs 中使用 v-for 时无限重复的主要内容,如果未能解决你的问题,请参考以下文章
解决vuejs无限死循环 - createdmounted重复不断执行
解决vuejs无限死循环 - createdmounted重复不断执行
解决vuejs无限死循环 - createdmounted重复不断执行
Vuejs - 如何使用 v-for 获取数组中的所有唯一值(删除重复项)