vue.js - 模板在 vue.js 中渲染两次
问题描述
在我的组件模板中,我有以下代码:
<div
class="program-point-container"
v-for="p in programPoints"
:key="p.id"
>
<div class="mt-6 mt-sm-3 mt-md-14 mb-3 font-weight-bold font-size-16" v-if="showDate(p.startsAt)">
{{new Date(p.startsAt) | moment('DD.MM.YYYY')}} // Humboldt Carré
</div>
</div>
我的 programPoints 数组中有 23 个对象。出于调试原因,我在控制台记录了一个字符串,以查看该函数被调用了 23 * 2 次。
在这种方法中,我将数据推送到数组中。并返回 true 或 false 以显示 div 容器。但是由于它已经在“第一次”渲染时推送并返回。我没有机会展示那个容器。
showDate(datetime) {
const date = new Date(datetime).toDateString()
// check if date already been pushed
if(this.dates.includes(date)) {
console.log('false')
return false // date already been pushed
}
this.dates.push(date)
console.log('true')
return true
},
解决方案
扔掉“JQuery 思维”。这不是 Vue 的工作方式。您的模板已经并且将被多次渲染 - 每次它使用的一些反应数据发生变化时......
您无需关心之前渲染的内容以及更新结果以获取新数据状态的操作。这是 Vue 的工作。只需以“我想在屏幕上看到的”样式编写您的模板,其余部分由 Vue 处理...
只需删除与此相关showDate
的所有内容 - 不需要。并阅读文档!
更新
在对象数组中,我有一个具有日期时间的属性。而且我只想在日期出现的第一个对象上显示一次日期。其余的忽略它。当出现新日期时,我希望它也显示它,但仅适用于第一个对象,依此类推
我想为对象添加一个额外的键,它是第一个迭代并具有唯一日期的对象。其他的将被忽略,直到另一个带有唯一日期。
Fight Club...ehm Vue 的第一条规则是:在模板渲染期间,切勿修改模板中使用的任何数据。在最好的情况下,您最终会得到不正确的结果(就像您所做的那样)。在最坏的情况下,你最终会出现无限循环......
更好的解决方案是创建表示您想要的替代数据结构,并且由于 Vue计算属性,即使原始数据发生更改,它也会保持最新......
const vm = new Vue({
el: "#app",
data() {
return {
programPoints: [
{ id: 1, name: 'Program A', startsAt: '2021/04/13' },
{ id: 2, name: 'Program B', startsAt: '2021/04/14' },
{ id: 3, name: 'Program C', startsAt: '2021/04/14' },
{ id: 4, name: 'Program D', startsAt: '2021/04/18' },
{ id: 5, name: 'Program E', startsAt: '2021/04/13' },
{ id: 6, name: 'Program F', startsAt: '2021/04/18' },
]
}
},
computed: {
programByDays() {
return this.programPoints.reduce((acc, item) => {
if(!acc[item.startsAt]) {
acc[item.startsAt] = []
}
acc[item.startsAt].push(item)
return acc
}, {})
}
},
mounted() {
setTimeout(() => this.programPoints.push({ id: 7, name: 'Program SPECIAL', startsAt: '2021/04/20' }), 2000)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<ul>
<li v-for="(programs, date) in programByDays" :key="date">
<p> {{ date }} </p>
<ul>
<li v-for="program in programs" :key="program.id">
{{ program.name }}
</li>
</ul
</li>
</ul>
</div>
推荐阅读
- android-studio - Android Studio Kotlin:ArrayAdapter 不会让我覆盖 getView 函数
- virtual-machine - 在一个 VMM 上运行的不同虚拟机是否共享来宾物理地址空间?
- java - 为 Java 解析 XML
- c - MSP430 上寄存器的按位运算符,无需取消引用
- node.js - 来自 html 表单 req.body 的快递表单为空
- javascript - 如何使用 jaavascript 或 jquery 在 iframe 中获取 li 数据属性
- java - 数据 jpa 的字段级加密
- python - 如何合并三个字典,使 1 个键具有多个单独的列表值
- python - 如何正确描述自定义 Record 的类型?
- python - 更改默认 Jupyter 配置目录