即使使用扩展运算符,组件渲染函数中也可能有无限更新循环,但 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 中触发另一个渲染,而最后一个不会触发状态更改(因为它正在更改该对象上的值而不是整个引用)并且不会触发另一个重新渲染。