首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >即使使用扩展运算符,组件渲染函数中也可能存在无限的更新循环

即使使用扩展运算符,组件渲染函数中也可能存在无限的更新循环
EN

Stack Overflow用户
提问于 2020-12-14 03:19:09
回答 2查看 97关注 0票数 1

我知道这个问题以前已经回答过了,但在查看了"You may have an infinite update loop in a component render function" warning in Vue component之后,我发现解决方案不起作用。

有人能帮我弄清楚这是怎么回事吗?

代码语言:javascript
复制
<template>
  <div>
    <template v-for="listing in sortedListings">
      <listing
        :key="listing.uuid"
        :listing="listing"
        :highlight-color="listing.highlight ? getHighlightColor() : null"
      />
    </template>
  </div>
</template>

<script>
import Listing from '@/components/Listing'
export default {
  components: {
    Listing,
  },
  data: function () {
    return {
      highlightColors: this.getHighlightColors(),
      listings: [
        {
          uuid: '658f325f-33c8-455b-98f6-27eb4eaa16a0',
          title: 'Cursus Nullam Amet Tortor',
          location: 'Remote',
          url: 'http://example.net/birds',
          hours_week: 20,
          tags: ['django', 'python', 'flask'],
          logo: 'https://logo.clearbit.com/apple.com',
          company_name: 'Apple',
          show_logo: 1,
          highlight: 0,
          stick_top: 0,
        },
        {
          uuid: '658f325f-33c8-455b-98f6-27eb4eaa16a1',
          title: 'Donec id elit non mi porta gravida at eget metus',
          location: 'Remote',
          url: 'http://example.net/birds',
          hours_week: 20,
          tags: ['django', 'python', 'flask', 'full-stack', 'contract'],
          logo: 'https://logo.clearbit.com/apple.com',
          company_name: 'Mapple',
          show_logo: 0,
          highlight: 0,
          stick_top: 0,
        },
        {
          uuid: '658f325f-33c8-455b-98f6-27eb4eaa16a2',
          title:
            'Donec ullamcorper nulla non metus auctor fringilla ullamcorper dapibus',
          location: 'Remote / USA',
          url: 'http://example.net/birds',
          hours_week: 20,
          tags: ['django', 'python', 'flask', 'full-stack', 'vue.js'],
          logo: 'https://logo.clearbit.com/apple.com',
          company_name: 'Fapple',
          show_logo: 1,
          highlight: 0,
          stick_top: 1,
        },
        {
          uuid: '658f325f-33c8-455b-98f6-27eb4eaa16a3',
          title: 'Tristique Euismod Venenatis Porta',
          location: 'San Francisco, CA, USA',
          url: 'http://example.net/birds',
          hours_week: 20,
          tags: ['django', 'python', 'flask', 'full-stack', 'vue.js'],
          logo: 'https://logo.clearbit.com/apple.com',
          company_name: 'Lapple',
          show_logo: 1,
          highlight: 1,
          stick_top: 0,
        },
        {
          uuid: '658f325f-33c8-455b-98f6-27eb4eaa16a4',
          title: 'Tristique Euismod Venenatis',
          location: 'San Francisco, CA, USA',
          url: 'http://example.net/birds',
          hours_week: 20,
          tags: ['django', 'python', 'flask', 'full-stack', 'vue.js'],
          logo: 'https://logo.clearbit.com/apple.com',
          company_name: 'Dapple',
          show_logo: 1,
          highlight: 1,
          stick_top: 1,
        },
      ],
    }
  },
  computed: {
    sortedListings: function () {
      return [...this.listings].sort(function (a, b) {
        return b.stick_top - a.stick_top
      })
    },
  },
  methods: {
    getListings: async function () {},
    getHighlightColors: function () {
      return this.shuffleArray([
        '#E3F2FD',
        '#E8EAF6',
        '#FFEBEE',
        '#E0F2F1',
        '#E8F5E9',
        '#FFF3E0',
        '#FFFDE7',
      ])
    },
    getHighlightColor: function () {
      if (this.highlightColors.length === 0) {
        this.highlightColors = this.getHighlightColors()
      }
      return this.highlightColors.shift()
    },
  },
  mounted: function () {
    this.getListings()
  },
}
</script>

在计算属性sortedListings中,我已经在执行[...this.listings]

EN

回答 2

Stack Overflow用户

发布于 2020-12-14 03:51:31

扩展运算符不会深度克隆数组,排序方法会修改computed中使用的原始属性,从而生成无限循环,因此添加一个方法来深度克隆对象,如this one

代码语言:javascript
复制
...

 computed: {
    sortedListings: function () {
      return this.deepCopy(this.listings).sort(function (a, b) {
        return b.stick_top - a.stick_top
      })
    },
  },
  methods: {
   deepCopy(src) {
     let target = Array.isArray(src) ? [] : {};
     for (let prop in src) {
      let value = src[prop];
       if(value && typeof value === 'object') {
        target[prop] = deepCopy(value);
       } else {
        target[prop] = value;
      }
   }
     return target;
  }
  ,
    getListings: async function () {},
...
票数 2
EN

Stack Overflow用户

发布于 2020-12-14 04:10:37

getHighlightColor()导致了无限循环。

这是一个经典的例子,说明了为什么绑定到模板中的方法可能是不好的(并不总是)。如果你的方法改变了一个模型,Vue必须重新渲染组件。然后触发该方法并再次更改模型,然后导致组件的重新呈现,依此类推。

此演示将产生相同的结果,但如果您使用模板中的计算结果,则不会:

代码语言:javascript
复制
new Vue({
  el: "#app",
  data() {
    return {
      arr: [1,2,3,4,5]
    }
  },
  methods: {
    change: function () {
      return this.arr.shift();
    },
  },
  computed: {
    test() {
      return this.arr.shift();
    }
  }
});
代码语言:javascript
复制
<div id="app">
  <div>
    {{ change() }}
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65279644

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档