javascript - Vue组件中的无限更新循环
问题描述
我的导航选项卡组件中出现以下更新错误:
您可能在组件渲染函数中有无限更新循环。
回顾这里以前的问题,大多数似乎与计算属性有关,或者直接修改传递给组件的道具,迫使它们不断地重新渲染。然而,在这个组件中,我认为我也不想这样做。
Vue.component('navigation-tabs', {
props: {
tabs: Array,
title: String,
type: String
},
data() {
return {
navigationTabs: Vue.util.extend([], this.tabs),
selectedTab: {},
tabCounter: 0,
tabType: this.type ? this.type : 'tabs'
}
},
methods: {
navItemClasses(selectedTab) {
if (selectedTab.selected) {
if (this.type) {
return 'bg-gradient-dark text-white';
}
} else if (selectedTab.disabled === true) {
return 'text-danger';
}
},
selectTab(selectedTab) {
if (selectedTab.disabled !== true) {
this.navigationTabs.forEach(tab => {
tab.selected = false;
});
selectedTab.selected = true;
}
}
},
computed: {
activeComponent() {
return this.navigationTabs.filter(x => x.selected === true)[0]
}
},
template: `
<div>
<div>
<ul class="text-md nav" :class="tabType === 'tabs' ? 'nav-tabs' : 'nav-pills'">
<li v-for="(tab, index) in navigationTabs" class="nav-item card-img-holder" v-if="tab.hideForSite !== $parent.site">
<img src="/shared/resources/images/circle.svg" class="card-img-absolute">
<a class="nav-link font-weight-bold" :class="navItemClasses(tab)" @click="selectTab(tab)">
{{ tabCounter++ + ': ' + tab.name }}
</a>
</li>
<h3 v-if="title" class="nav-link font-weight-bold ml-auto pb-0">{{ title }}</h3>
</ul>
</div>
<div v-if="tabType !== 'tabs'" class="border-top my-3"></div>
<div class="my-4 mx-5">
<component :is="activeComponent.component"></component>
</div>
</div>
`,
});
我什至只是在尝试在屏幕上显示/记录tabCounter的值时才发现这一点,这样我就可以在每个显示的选项卡旁边显示一个准确的数字。如果我移除计数器,我根本不会收到错误,这对我来说似乎很不寻常,因为我并没有真正用它做太多事情。这让我担心后台出了什么问题,因为即使我只有 6 个选项卡要显示,计数器也会循环到超过 700 的值。
我在下面包含了父应用程序的副本以供参考,任何帮助将不胜感激。
let app = new Vue({
el: '#app',
data: {
site: '1',
myTabs: [
{
name: 'Example 1',
selected: true,
component: 'example-one'
},
{
name: 'Example 2',
component: 'example-two'
},
{
name: 'Example 3',
component: 'example-three'
},
{
name: 'Example 4',
component: 'example-four'
},
{
name: 'Example 5',
component: 'example-five',
hideForSite: 'DC4'
},
{
name: 'Example 6',
component: 'example-six'
},
{
name: 'Example 7',
disabled: true
},
]
},
created() {
this.site = document.cookie.match('(^|;) ?' + 'Siteinstance' + '=([^;]*)(;|$)')[2].toUpperCase();
}
});
编辑:最初我没有在模板中进行增量,而是调用了一个函数,但不明白为什么它被调用了 600 多次:
<a class="nav-link font-weight-bold" :class="navItemClasses(tab)" @click="selectTab(tab)">
{{ retrievePosition() + ': ' + tab.name }}
</a>
retrievePosition(){
return this.tabCounter++;
},
解决方案
tabCounter++
tabCounter
每次渲染组件时都会更新,这会导致重新渲染并导致无限循环。
如果需要计数器,则已经有索引值:
{{ (index + 1) + ': ' + tab.name }}
尽量避免在渲染过程中(在组件模板和函数内部)产生副作用,render
因为这是一种不好的做法,可能会导致无限循环。如果应该不断执行副作用,那么观察者beforeUpdate
和updated
生命周期钩子是合适的地方。
推荐阅读
- firebase - 使用 sinon 模拟 admin.firestore().batch()
- python - 为 ncks 创建循环以使用 Python 从 Hycom 中提取 NetCDF 数据
- javascript - 为什么我的 for await 循环在异步迭代器中无限循环?
- json - 如何在powershell中将JSON键和值捕获为数组
- java - Jetty 11. 使用 Godaddy 证书的安全连接失败
- html - CSS边框属性为边框添加了几层
- jquery - Jquery:如何在一串文本中查找单独的数字集并向它们添加href标签
- arrays - 在 Fauna db 中过滤嵌套的文档树?
- javascript - 在 JavaScript 中将 Json 对象解析为二维数组
- google-cloud-platform - Terraform 试图覆盖我已经创建的 gcp 资源组,同时尝试创建另一个资源组