【问题标题】:Deleting specific component in v-for array删除 v-for 数组中的特定组件
【发布时间】:2019-08-28 18:48:41
【问题描述】:

我有下面的数组,其中包含许多列。下面的示例包含三列,但可以动态添加/删除列:

[['position', '30'], ['position', '60'], ['position', '90']]

我在使用 Vue 删除 正确 列(数组中的索引)时遇到问题。

考虑下面的sn-p:

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    columns: [['position', '30'], ['position', '60'], ['position', '90']]
  },
  methods: {
  	deleteColumn: function(index) {
    	this.columns.splice(index, 1);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  
  <div v-for="(item, index) in columns" :key="index">
  Column #: {{index}} - <a @click="deleteColumn(index)">Delete me</a>
  
  </div>
  
</div>

如果你运行上面的代码 sn -p end 尝试删除#1 列,它实际上会删除#2 列(数组的最后一项)。 #0 也是如此。

我认为通过将index 提供给我的deleteColumn 函数,我可以从数组中删除“正确”索引。

感谢任何帮助。

【问题讨论】:

  • @oliverbj 是唯一的位置值,或者您可以为每个值添加一个id 吗?
  • 这些值不是唯一的。如果需要,可以在渲染之前“重新映射”数组(所以可以,并且可以添加 id)

标签: javascript vue.js vuejs2


【解决方案1】:

只需给他们一个属性名称,你就完成了。请注意我在这里所做的更改。 Columns 不再是二维数组,而是对象。使用this.$delete(this.columns, index); 删除对象。

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    columns: {
      '1': {
        position: 30
      },
      '2': {
        position: 60
      },
      '3': {
        position: 90
      }
    }
  },
  methods: {
    deleteColumn: function(index) {
      this.$delete(this.columns, index);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">

  <div v-for="(item, index) in columns" :key="index">
    Column #: {{index}} - <a @click="deleteColumn(index)">Delete me</a>

  </div>

</div>
{
  '1': {
    position: 30
  },
  '2': {
    position: 60
  },
  '3': {
    position: 90
  }
}

这里,'1' 是一个属性名,它的值是另一个对象。这就像为您的数据提供 ID。

对象值的格式是这样的

{ property_name : value }

这里,value 是另一个对象,在那个对象中,还有另一个属性,名为“position”,对应的值。

【讨论】:

  • 啊!现在我只需要弄清楚如何添加属性名称。
  • 只要"property_name" : { obj : value } 这个就跟position: 90 一样,这里的位置是一个属性名,而这里的“property_name”是另一个对象。 @oliverbj
  • 您介意在您的答案中包含它吗?如何将属性名称设置为 1、2 3 等?
【解决方案2】:

当您以正确的方式单击任何项​​目时,您的索引就是您的关键,这就是问题所在,但从视觉上看,在逻辑上它是正确的。在模板中显示您的位置,以便您可以看到它。对我来说,你的数据不正确。

<div id="app">
     <div v-for="(item, index) in columns" :key="index">
         Column #: {{index}}-{{item.position}} - 
         <a @click="deleteColumn(index)">Delete me</a>
     </div>  
</div>

你的脚本可以看到变化

new Vue({
 el: '#app',
 data: {
  message: 'Hello Vue.js!',
  columns: [{position: 30}, {position: 60}, {position: 90}]
 },
 methods: {
  deleteColumn: function(index) {     
    this.columns.splice(index, 1);
  }
 }
})

【讨论】:

  • 知道如何在视觉上删除“正确”的项目吗?
  • 改变你的数据和模板是这样的:template =
    Column #: {{index}}-{{item.position}} - 删除我
    脚本 = 列:[{position :30},{位置:60},{位置:90}]
【解决方案3】:

splice 方法重新索引数组,向上或向下移动拼接点之后的所有元素,以便任何新插入的值都适合并且数组索引保持连续。如果您还显示列表中项目的值,您可以更清楚地看到它:

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    columns: ['foo', 'bar', 'baz']
  },
  methods: {
    deleteColumn: function(index) {
      this.columns.splice(index, 1);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="(item, index) in columns" :key="index">
  Column #{{index}} = {{item}} - <a @click="deleteColumn(index)" style="cursor:pointer">Delete me</a>      
  </div>
</div>

最初,上面的 sn-p 将呈现如下:

第 0 列 = foo - 删除我
第 1 列 = 栏 - 删除我
第 2 列 = baz - 删除我

如果您现在单击第 0 列(“foo”)上的“删除我”链接,它将变为:

第 0 列 = 栏 - 删除我
第 1 列 = baz - 删除我

你可以看到值“foo”确实从数组中拼接出来了——值“bar”和“baz”被向下移动了一个位置成为新元素#0和#1。


无论如何,解决这个问题的方法就是“不要那样做”:

  • 如果您将 v-for 与一个元素没有自然键值的简单数组一起使用,您可以完全省略 :key 并让 Vue 决定如何最好地处理对底层数组的更改。只要v-for 循环中的内容不包含任何表单输入或有状态组件或其他对正在重新索引的数组反应不佳的花哨的东西,它就可以正常工作。

  • 相反,如果您确实有一个可用于每个数组元素的自然唯一键,请使用它。如果您不这样做,但可以创建一个,请考虑这样做。

【讨论】:

  • 感谢您的详细解答。说我映射数组以包含每个项目的唯一键“id”,可以使用哪种方法删除“正确”(至少 UI 方面)项目?
  • 如果我没有那个钥匙 - 该怎么办?
  • 您仍然可以使用您编写的deleteColumn() 函数。 Vue 会注意到索引何时更改并更新 @click 处理程序。或者,您也可以将数组替换为对象并使用唯一键作为属性名称,如{id01: 'foo', id02: 'bar', id03: 'baz'}。然后您可以直接使用它们的键引用值,并使用Vue.delete() 方法删除它们。
【解决方案4】:

不应该使用 index 作为 CRUD 操作的键,因为这会使 Vue 在删除时感到困惑。密钥应该是与数据相关的唯一标识符。

您可以使用从数组中的数据生成的密钥在挂载时创建一个新的格式化对象数组(注意:如果有任何错误,我还没有在浏览器中测试代码)。

<template>
  <div>
    <div v-for="col in formattedColumns" :key="col.key">
      {{ col.value }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      columns: [['position', '30'], ['position', '60'], ['position', '90']],
      formattedColumns: null,
    };
  },
  mounted() {
    let columns = [];
    for (let i = 0; i < this.columns.length; i++) {
      columns.push({
        value: this.columns[i],
        key: this.columns[i][0] + this.columns[i][1],
      });
    }

    this.formattedColumns = columns;
  },
};
</script>

【讨论】:

    【解决方案5】:

    试试这个this.$delete(this.columns, index),它和Vue.delete(this.columns, index)是一样的

    https://vuejs.org/v2/api/index.html#Vue-delete

    【讨论】:

    • 试一试,一切正常! deleteColumn: function(index) { this.$delete(this.columns, index); }
    猜你喜欢
    • 2019-03-04
    • 2019-01-16
    • 1970-01-01
    • 2021-12-21
    • 2014-10-12
    • 2012-09-10
    • 2019-01-25
    • 2016-11-11
    相关资源
    最近更新 更多