---
title: 'Про vue.js и рендергинг v-for'
url: 'https://graker.ru/news/2018/04/03/vuejs-v-for-rendering'
language: ru
type: post
author: 'Роман Грачев'
published: '2018-04-03T14:40:00+03:00'
updated: '2019-05-28T11:29:35+03:00'
categories:
  - Программирование
  - Vue.js
---

# Про vue.js и рендергинг v-for

Какое-то время пилю некоторое приложение на Laravel. На этот раз, для разнообразия, решил попробовать прилагающийся по умолчанию фронт-энд. На [Vue.js](https://vuejs.org/) который.

Не могу сказать, что обрел уже просветление и стал гурой, понимание предмета пока еще несколько клиповое. Но в целом после привычного ангуляра диким зверем фреймворк не выглядит, получается достаточно стройно и понятно. Хотя какие-то вещи и могут казаться странными.

В процессе освоения и использования, набрёл на любопытный хак. Захотелось мне, значит, сделать множество полей с автодополнением, примерно так (упрощенно):

```
<ol>
    <li v-if="people" v-for="(person, index) in people">
        <autocomplete
            url="/people/search_by_name"
            anchor="name"
            label="email"
            :initValue="person.name"
            :onInput="autocompleteNameChanged"
            :onSelect="autocompleteGetData"></autocomplete>
        <button type="button" v-on:click="removePerson($event, index)" class="btn btn-default"><span class="fa fa-times"></span></button>
    </li>
</ol>
```

Это поле автодополнения, а справа у каждого экземпляра кнопка для удаления с простым обработчиком:

```
removePerson: function (event, index) {
    event.preventDefault();

    this.people.splice(index, 1);
},
```

Проблема в том, что по нажатии на удаление визуально удаляется не выбранный элемент, а последний. Вот так:

![1](https://graker.ru/sites/default/files/styles/max_1300x1300/public/media/misc-images/list_incorrect.gif.webp?itok=VFEdM00L)

Под капотом-то всё правильно происходит, если сохранить форму — удаленным окажется именно выбранный элемент. Но визуально это совсем не очевидно.

Вообще, во Vue.js есть такой атрибут [`:key`](https://ru.vuejs.org/v2/guide/list.html#key). Судя по описанию — то что надо. Но вот незадача: если у `person` еще нет уникального `id`, потому что мы работаем с формой создания, ничего не выйдет. Если в `:key` поместить просто `index`, то есть, порядковый номер — результат будет такой же, как на гифке выше.

Побродив по форумам в попытках обнаружить решение, наткнулся на занятный совет. Изменение атрибута `:key` заставит Vue перерендерить список. То есть можно задать автодополнениям одно какое-то значение (не забудьте проинициализировать):

```
<autocomplete
    ...
    :key="update_component_key"
    ...
    :onSelect="autocompleteGetData"></autocomplete>
```

И обновлять его каждый раз, когда массив `people` изменился и нужно перерендерить поля:

```
removePerson: function (event, index) {
    event.preventDefault();

    this.people.splice(index, 1);
    this.update_component_key ++;
}
```

Так — работает:

![1](https://graker.ru/sites/default/files/styles/max_1300x1300/public/media/misc-images/list_correct.gif.webp?itok=Z4wzhQm6)

В следующий раз можно посмотреть, например, как работают сами поля автодополнений (на основе [существующего компонента](https://www.npmjs.com/package/vue2-autocomplete-js), не самописные).
