即使使用扩展运算符,组件渲染函数中也可能有无限更新循环,但 Object.assign 效果很好
You may have an infinite update loop in a component render function even with spread operator, but Object.assign works well
我一直认为object.assign和展开算子很相似
但是今天,我有一个错误'You may have an infinite update loop in a component render'
提前声明,父对象的结构是这样的:
我尝试了以下三种方式:
一:传播运算符,得到这个错误'You may have an infinite update loop in a component render'
const template = { ...parent , path: '', noShowingChildren: true }
this.onlyOneChild = template
二:Deep Copy,报错'You may have an infinite update loop in a component render'
const template = JSON.parse(JSON.stringify(parent))
template.path = ''
template.noShowingChildren = true
this.onlyOneChild = template
三个:Object.assign,工作正常。
const template = Object.assign(parent, { path: '', noShowingChildren: true })
this.onlyOneChild = template
这三种情况,结果让我感到很迷茫。
有人可以帮我回答这个问题吗?
这里是 code.Thank 你的帮助。
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<router-link
v-if="onlyOneChild.meta"
:to="resolvePath(onlyOneChild.path)"
>
<el-menu-item
:index="getIndex(onlyOneChild.path)"
:class="{'submenu-title-noDropdown':!isNest}"
>
<item
v-if="onlyOneChild.meta"
:icon="onlyOneChild.meta.icon||item.meta.icon"
:title="onlyOneChild.meta.title"
/>
</el-menu-item>
</router-link>
</template>
export default {
name: 'SidebarItem',
components: { Item, AppLink },
props: {
// route object
item: {
type: Object,
required: true
},
isNest: {
type: Boolean,
default: false
},
basePath: {
type: String,
default: ''
}
},
data () {
return {
onlyOneChild: null
}
},
methods: {
hasOneShowingChild (children, parent) {
const showingChildren = children.filter(item => {
// console.log(item)
if (item.meta.hidden) {
return false
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
}
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
console.log('this is parent object:', parent)
// const template = { ...parent , path: '', noShowingChildren: true }
// const template = { ...JSON.parse(JSON.stringify(parent)), path: '', noShowingChildren: true }
// const template = JSON.parse(JSON.stringify(parent))
// template.path = ''
// template.noShowingChildren = true
const template = Object.assign(parent, { path: '', noShowingChildren: true })
this.onlyOneChild = template
return true
}
return false
}
}
}
您使用的前两种方法(解析 JSON 和传播)将创建新的对象或引用,而最后一种方法(赋值)将使用完全相同的方法并为其分配新值.所以我只能假设前两个将通过完全更改 this.onlyOneChild
来触发状态更新,这将在 return 中触发另一个渲染,而最后一个不会触发状态更改(因为它正在更改该对象上的值而不是整个引用)并且不会触发另一个重新渲染。
我一直认为object.assign和展开算子很相似
但是今天,我有一个错误'You may have an infinite update loop in a component render'
提前声明,父对象的结构是这样的:
我尝试了以下三种方式:
一:传播运算符,得到这个错误'You may have an infinite update loop in a component render'
const template = { ...parent , path: '', noShowingChildren: true }
this.onlyOneChild = template
二:Deep Copy,报错'You may have an infinite update loop in a component render'
const template = JSON.parse(JSON.stringify(parent))
template.path = ''
template.noShowingChildren = true
this.onlyOneChild = template
三个:Object.assign,工作正常。
const template = Object.assign(parent, { path: '', noShowingChildren: true })
this.onlyOneChild = template
这三种情况,结果让我感到很迷茫。
有人可以帮我回答这个问题吗?
这里是 code.Thank 你的帮助。
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<router-link
v-if="onlyOneChild.meta"
:to="resolvePath(onlyOneChild.path)"
>
<el-menu-item
:index="getIndex(onlyOneChild.path)"
:class="{'submenu-title-noDropdown':!isNest}"
>
<item
v-if="onlyOneChild.meta"
:icon="onlyOneChild.meta.icon||item.meta.icon"
:title="onlyOneChild.meta.title"
/>
</el-menu-item>
</router-link>
</template>
export default {
name: 'SidebarItem',
components: { Item, AppLink },
props: {
// route object
item: {
type: Object,
required: true
},
isNest: {
type: Boolean,
default: false
},
basePath: {
type: String,
default: ''
}
},
data () {
return {
onlyOneChild: null
}
},
methods: {
hasOneShowingChild (children, parent) {
const showingChildren = children.filter(item => {
// console.log(item)
if (item.meta.hidden) {
return false
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
}
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
console.log('this is parent object:', parent)
// const template = { ...parent , path: '', noShowingChildren: true }
// const template = { ...JSON.parse(JSON.stringify(parent)), path: '', noShowingChildren: true }
// const template = JSON.parse(JSON.stringify(parent))
// template.path = ''
// template.noShowingChildren = true
const template = Object.assign(parent, { path: '', noShowingChildren: true })
this.onlyOneChild = template
return true
}
return false
}
}
}
您使用的前两种方法(解析 JSON 和传播)将创建新的对象或引用,而最后一种方法(赋值)将使用完全相同的方法并为其分配新值.所以我只能假设前两个将通过完全更改 this.onlyOneChild
来触发状态更新,这将在 return 中触发另一个渲染,而最后一个不会触发状态更改(因为它正在更改该对象上的值而不是整个引用)并且不会触发另一个重新渲染。