Javascript 即使使用“扩展”操作符,组件渲染函数中也可能存在无限更新循环

Javascript 即使使用“扩展”操作符,组件渲染函数中也可能存在无限更新循环,javascript,vue.js,Javascript,Vue.js,我知道这个问题以前已经得到了回答,但在查看之后,我发现解决方案不起作用 有人能帮我弄清楚这是怎么回事吗 <template> <div> <template v-for="listing in sortedListings"> <listing :key="listing.uuid" :listing="listing" :

我知道这个问题以前已经得到了回答,但在查看之后,我发现解决方案不起作用

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

<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>

从“@/components/Listing”导入列表
导出默认值{
组成部分:{
表册
},
数据:函数(){
返回{
highlightColors:this.getHighlightColors(),
清单:[
{
uuid:'658f325f-33c8-455b-98f6-27eb4eaa16a0',
标题:“侵权者之咒”,
位置:'远程',
网址:'http://example.net/birds',
每周工作时数:20,
标记:['django','python','flask'],
标志:'https://logo.clearbit.com/apple.com',
公司名称:“苹果”,
show_logo:1,
推荐理由:0,
棒顶:0,
},
{
uuid:'658f325f-33c8-455b-98f6-27eb4eaa16a1',
标题:“在eget metus的Donec id elit非mi porta孕妇”,
位置:'远程',
网址:'http://example.net/birds',
每周工作时数:20,
标记:['django','python','flask','full stack','contract'],
标志:'https://logo.clearbit.com/apple.com',
公司名称:“Mapple”,
显示\u徽标:0,
推荐理由:0,
棒顶:0,
},
{
uuid:'658f325f-33c8-455b-98f6-27eb4eaa16a2',
标题:
“Donec ullamcorper nulla non metus拍卖商fringilla ullamcorper dapibus”,
位置:“远程/美国”,
网址:'http://example.net/birds',
每周工作时数:20,
标签:['django','python','flask','full stack','vue.js'],
标志:'https://logo.clearbit.com/apple.com',
公司名称:“Fapple”,
show_logo:1,
推荐理由:0,
杆顶:1,
},
{
uuid:'658f325f-33c8-455b-98f6-27eb4eaa16a3',
标题:“特里斯蒂克·尤伊斯莫·维尼纳蒂斯门”,
地点:美国加利福尼亚州旧金山,
网址:'http://example.net/birds',
每周工作时数:20,
标签:['django','python','flask','full stack','vue.js'],
标志:'https://logo.clearbit.com/apple.com',
公司名称:“Lapple”,
show_logo:1,
亮点:一,,
棒顶:0,
},
{
uuid:'658f325f-33c8-455b-98f6-27eb4eaa16a4',
标题:“特里斯蒂克·尤伊斯莫·维内纳蒂斯”,
地点:美国加利福尼亚州旧金山,
网址:'http://example.net/birds',
每周工作时数:20,
标签:['django','python','flask','full stack','vue.js'],
标志:'https://logo.clearbit.com/apple.com',
公司名称:“Dapple”,
show_logo:1,
亮点:一,,
杆顶:1,
},
],
}
},
计算:{
分类列表:函数(){
return[…this.listings].sort(函数(a,b){
返回b.斗杆顶部-a.斗杆顶部
})
},
},
方法:{
getListings:async函数(){},
GetHighlightColor:函数(){
把这个还给我([
“#E3F2FD”,
“#E8EAF6”,
#FFEBEE",,
“#E0F2F1”,
"E8F5E9",,
"FFF3E0",,
"FFFDE7",,
])
},
getHighlightColor:函数(){
if(this.highlightColors.length==0){
this.highlightColors=this.getHighlightColors()
}
返回此.highlightColors.shift()
},
},
挂载:函数(){
这个文件名为getListings()
},
}

在computed属性
sortedListings
中,我已经在执行
[…this.listings]
扩展运算符不会深度克隆数组,排序方法会修改生成无限循环的computed中使用的原始属性,因此添加一个方法来深度克隆对象,如:


spread操作符不会深度克隆数组,而sort方法会修改生成无限循环的computed中使用的原始属性,因此请添加一个方法来深度克隆对象,如下所示:

getHighlightColor()
导致无限循环

这是一个典型的例子,说明了为什么绑定到模板中的方法是不好的(并非总是如此)。如果您的方法更改了模型,Vue必须重新加载组件。然后触发该方法并再次更改模型,从而导致组件重新加载,依此类推

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

newvue({
el:“应用程序”,
数据(){
返回{
arr:[1,2,3,4,5]
}
},
方法:{
更改:函数(){
返回此.arr.shift();
},
},
计算:{
测试(){
返回此.arr.shift();
}
}
});

{{change()}}
getHighlightColor()
导致无限循环

这是一个典型的例子,说明了为什么绑定到模板中的方法是不好的(并非总是如此)。如果您的方法更改了模型,Vue必须重新加载组件。然后触发该方法并再次更改模型,从而导致组件重新加载,依此类推

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

newvue({
el:“应用程序”,
数据(){
返回{
arr:[1,2,3,4,5]
}
},
方法:{
更改:函数(){
返回此.arr.shift();
},
},
计算:{
测试(){
返回此.arr.shift();
}
}
});

{{change()}}

刚刚试过。不起作用:(只是尝试了一下。不起作用:(我明白你的意思。我只是将computed属性更改为一个方法。但是我仍然得到了错误。你已经得到了错误。你必须将该方法更改为ComputedWhat方法?抱歉
getHighlightColor()
@JacobHyde我没有重现代码,我集中精力
...

 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 () {},
...