Vue中v-for循环内v-if下c++输出异常的原因咨询
问题原因及解决方案
先看你的代码:
<template> <div id="app"> <div v-for="b in a"> <div v-if="b === 3" > {{ c++ }} </div> <p>{{ b }}</p> </div> </div> </template> <script> export default { data() { return { a: [1, 2, 3, 4, 5, 4, 3, 2, 1], c: 0 } } } </script>
为什么会出现异常?
核心问题在于你把c++这种有副作用的操作直接写在了模板表达式里:
- Vue的模板表达式会在组件的每次渲染(包括初始渲染、响应式数据更新触发的重渲染)时被执行,开发环境下Vue还会做双重校验,表达式可能执行多次。
- 每次执行
{{ c++ }}都会修改c的值,而c是响应式数据,修改后又会触发组件重新渲染,形成循环,最终导致c被执行了上百次,数值变得极大。 - 另外,Vue要求模板表达式必须是纯函数(无副作用),直接修改数据的操作本身就违反了这个规则,必然会引发不可预测的行为。
怎么解决?
不要在模板里直接修改数据,提前计算好需要展示的内容,推荐用计算属性处理:
<template> <div id="app"> <div v-for="(item, index) in processedList" :key="index"> <div v-if="item.value === 3"> {{ item.count }} </div> <p>{{ item.value }}</p> </div> </div> </template> <script> export default { data() { return { a: [1, 2, 3, 4, 5, 4, 3, 2, 1], } }, computed: { processedList() { let count = 0 return this.a.map(num => { if (num === 3) count++ return { value: num, count: num === 3 ? count : 0 } }) } } } </script>
这个方案里,我们通过计算属性processedList提前遍历数组,统计每个3对应的序号,模板里只负责展示计算好的结果,既符合Vue的规范,也能得到你预期的1、2的输出。
内容的提问来源于stack exchange,提问作者linbob
相关产品推荐
相关产品推荐

