Vue indexOf vs vanilla javascript для выбора объекта из массива

1

Я видел несколько примеров, в которых indexOf используется в Vue для выбора объекта из массива таких объектов:

Автор сценария:

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    items: [
        {
        id: 1,
        name: 'test'
      },
      {
        id: 2,
        name: 'hello'
      },
      {
        id: 3,
        name: 'world'
      }
    ]
  },
  methods: {
    deleteItem(item) {
      console.log(this.items.indexOf(item));
      // splice the item.
    }
  }
})

Шаблон:

<script src="https://unpkg.com/vue"></script>

<div id="app">
  <p>{{ message }}</p>

  <ul>
    <li v-for="item in items" @click=deleteItem(item)>
      {{ item.name }}
    </li>
  </ul>
</div>

https://jsfiddle.net/5gwtyv3h/

Теперь мне интересно, что это даже возможно. Если я войду в консоль и просто сделаю это:

const items = [
    {
        id: 1,
        name: 'test'
    },
    {
        id: 2,
        name: 'hello'
    },
    {
        id: 3,
        name: 'world'
    }
];

items.indexOf({ id: 1, name: 'test'});

Я получаю -1, потому что элемент не найден. Vue делает что-то, что делает это возможным, или я пропустил что-то еще здесь?

  • 1
    Ваш тест всегда возвращает -1, потому что литерал объекта, который вы передаете, отсутствует в массиве items. Сравнение объектов не включает в себя содержимое объекта; они основаны на ссылках объекта.
  • 1
    Возможный дубликат разницы между indexOf и функцией findIndex массива
Показать ещё 3 комментария
Теги:
ecmascript-6
vue.js
vuejs2
vue-component

1 ответ

3

Вам нужно будет кэшировать объект, который вы добавляете в массив, или выполнить глубокое find() или findIndex().

Для объектов по сравнению с indexOf они должны быть одним и тем же объектом, то есть они должны ссылаться на один и тот же экземпляр объекта.

const a = {
    foo: "bar"
  },
  b = {
    foo: "bar"
  };

console.log(a === b); // false

Учти это:

const a = {
    foo: "bar"
  },
  b = {
    foo: "bar"
  };

const c = [a, b];

console.log(c.indexOf({
  foo: "bar"
})); // -1 since the Object you **just** made won't be in the array

console.log(c.indexOf(a)); // 0 you're looking for the right object by reference

console.log(c.findIndex(i => i.foo === "bar")); // 0 again since it does a deep compare

// Succinct deep compare using lodash
console.log(_.findIndex(c, i => _.isEqual(i, {
  foo: "bar"
}))); // 0 again but deep compare logic is encapsulated
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
  • 0
    Спасибо, я чувствую, что это недостаточно объяснено. Документация об indexOf похоже, отсутствует в этой части.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню