【问题标题】:VueJS Typescript WebPack, impossible to remove object from array with splice or deleteVueJS Typescript WebPack,无法通过拼接或删除从数组中删除对象
【发布时间】:2019-04-03 21:42:22
【问题描述】:

我尝试在 vueJS 中从数组中删除一个对象,但这是不可能的。

我做了很多事情并阅读了一些关于 stackoverflow 的解决方案,但对我没有任何帮助。

我的 vue.html 组件中有一个像这样的假列表:

<div class="custo-list-c">
  <div v-for="(item, index) in valuesFounded" 
    @click="addItem(item)"
    v-bind:class="{ 'selected': itemSelected(item) }">
    {{ item.value }}
    <span v-if="itemSelected(item)">
      <i class="fa fa-remove" @click="itemDeleted(item)"></i>
    </span>
  </div>
</div>

我的组件看起来像这样:

import Vue from 'vue';
import Component from 'vue-class-component';
import { Prop, Watch, Emit } from "vue-property-decorator";

@Component({
  name: 'custolist-component',
  template: require('./custo-list.component.vue.html'),
  components: {}
})
export default class CustoListComponent extends Vue {

  public custoListActive: boolean = false;
  public valuesFounded: Array<{key: string, value: string}> = [];

  public selectedItems_: Array<{key: string, value: string}> = [];

  @Prop() list;
  @Watch('list') onListChanged(newList, oldList) {
    // this.list = newList;
  }

  @Prop() placeholder;
  @Watch('placeholder') onPlaceholderChanged(newPlaceholder, oldPlaceholder) {
    // console.log(newPlaceholder);
  }

  @Prop() disabled;
  @Watch('disabled') onDisabledChanged(newDisabled, oldDisabled) {
    // console.log(newPlaceholder);
  }

  public open(event) {
    this.custoListActive = true;
    if (!event.target.value) {
      this.valuesFounded = this.list;
    } else {
      this.valuesFounded = [];
      const re = new RegExp(event.target.value, 'ig');
      for (var i=0; i<this.list.length; i++) {
        if (this.list[i].key.match(re) || this.list[i].value.match(re)) {
          this.valuesFounded.push(this.list[i]);
        }
      }
    }
  }

  public addItem(item: {key: string, value: string}) {

    if (!this.isSelectedItem_(item)) {
      this.selectedItems_.push(item);
      // this.custoListActive = false;
    };

    this.$emit('itemclicked', item);
  }

  public itemSelected(item) {
    return this.isSelectedItem_(item);
  }

  public itemDeleted(item) {
    for (var i=0; i<this.selectedItems_.length; i++) {
      if (item.key == this.selectedItems_[i].key) {
        this.selectedItems_.splice(i, 1);
        break;
      }
    }
    this.$emit('itemdeleted', item);
  }

  private isSelectedItem_(item) {
    const filtered = this.selectedItems_.filter(m => {
      return m.key == item.key;
    });

    return filtered.length > 0;
  }
}

但是当我做this.selectedItems_.splice(i, 1); 时,它不起作用!!

感谢您的帮助

我的代码更精确。这是我从数组中删除项目的方法:

public itemDeleted(item) {
  const filtered = this.selectedItems_.filter(m => {
    return m.key != item.key;
  });

  console.log(filtered, this.selectedItems_.length);
  this.selectedItems_ = filtered;
  console.log(this.selectedItems_, this.selectedItems_.length);

  this.$emit('itemdeleted', item);
}

以及控制台中的结果

console

怎么了?

另一个测试:

  public itemDeleted(item) {
    this.selectedItems_ = this.selectedItems_.filter(m => {
      return m.key != item.key;
    });

    this.selectedItems_.splice(this.selectedItems_.length);
    console.log(this.selectedItems_, this.selectedItems_.length);
    this.selectedItems_ = [];
    console.log(this.selectedItems_, this.selectedItems_.length);

    this.$emit('itemdeleted', item);
  }

结果:

console

可能是 VueJS 的一个错误

对不起,是我的错,更换

<i class="fa fa-remove" @click="itemDeleted(item)"></i>

<i class="fa fa-remove" v-on:click.stop="itemDeleted(item)"></i>

【问题讨论】:

    标签: javascript typescript vue.js webpack splice


    【解决方案1】:

    使用for 循环和if 语句的组合来查找价值的多个步骤会降低可读性和代码可预测性。此外,调用数组变异方法splice 可能不会触发该属性的响应式更新。

    我建议使用filter 并在itemDeleted 方法中重新分配selectedItems_,如下所示:

    public itemDeleted(item) {
      this.selectedItems_ = this.selectedItems_.filter(selectedItem => selectedItem.key !== item.key)
      this.$emit('itemdeleted', item);
    }
    

    这样,在方法执行后,selectedItems_ 将包含所有先前的项目,除了作为方法参数提供的项目之外,所有相关属性都将被重新计算。

    【讨论】:

    • 是的,感谢@aBiscuit 的回答,我也这样做了,但我的问题没有任何改变。在角度拼接上不是问题,但在 vuejs 上我遇到了一些错误。但你适合重构。
    • 您能否验证单击图标后是否正在调用click 处理程序itemDeleted?您可以通过将console.log 语句或debugger 放在itemDeleted 方法的第一行来做到这一点。
    • 总是调用 itemDeleted。私有 var selectedItems_ 中包含的所有值都是 Oberver 类型。这个变量被 vuejs 框架作为一个观察者在 console.log 上监听。数组的长度不会改变。可能需要在 javascript 模式下使用简单的 test.html 尝试使用 vuejs,看看这个问题是否再次出现
    • 请尝试将itemDeleted 方法中的分配更改为this.selectedItems_ = []。并验证数组长度没有改变。
    • 我也试过了。真的,我做了很多事情,但没有任何工作。可能是我的代码有问题。我尝试将一个空数组分配给变量并清除列表,然后再将对象重新分配给循环中的列表。
    猜你喜欢
    • 1970-01-01
    • 2016-07-21
    • 2013-05-05
    • 2023-01-13
    • 2017-04-29
    • 2012-07-16
    • 1970-01-01
    • 2010-10-04
    • 2018-11-13
    相关资源
    最近更新 更多