Почему я должен добавлять уникальный ключ при использовании v-for?

внешний интерфейс Vue.js

впервые опубликовано вличный блог

ключ в v-для

использоватьv-forПри обновлении отображаемого списка элементов по умолчанию используется就地复用Стратегия: когда данные списка изменены, он будет судить, изменено ли значение в соответствии со значением ключа, если оно изменено, повторно визуализировать этот элемент, в противном случае повторно использовать предыдущий элемент; Мы используем использование часто будем использоватьindex(то есть нижний индекс массива) какkey, но на самом деле это метод, который не рекомендуется;

дать 🌰

const list = [
    {
        id: 1,
        name: 'test1',
    },
    {
        id: 2,
        name: 'test2',
    },
    {
        id: 3,
        name: 'test3',
    },
]
<div v-for="(item, index) in list" :key="index" >{{item.name}}</div>

Приведенный выше сценарий часто используется в наших проектах.Поскольку ключ не добавляется, Vue теперь напрямую сообщает об ошибке, поэтому я использую индекс в качестве ключа; две распространенные ситуации обновления данных перечислены ниже.

1. Добавьте другие данные после последних данных

const list = [
    {
        id: 1,
        name: 'test1',
    },
    {
        id: 2,
        name: 'test2',
    },
    {
        id: 3,
        name: 'test3',
    },
    {
        id: 4,
        name: '我是在最后添加的一条数据',
    },
]

В это время первые три фрагмента данных повторно используются ранее, а последний фрагмент данных заново визуализируется.indexв видеkey,Нет проблем;

2. Вставьте часть данных посередине

const list = [
    {
        id: 1,
        name: 'test1',
    },
    {
        id: 4,
        name: '我是插队的那条数据',
    }
    {
        id: 2,
        name: 'test2',
    },
    {
        id: 3,
        name: 'test3',
    },
]

Обновите данные рендеринга в это время,indexОпределенныйkeyЧтобы сравнить данные до и после, мы обнаружили, что

之前的数据                         之后的数据

key: 0  index: 0 name: test1     key: 0  index: 0 name: test1
key: 1  index: 1 name: test2     key: 1  index: 1 name: 我是插队的那条数据
key: 2  index: 2 name: test3     key: 2  index: 2 name: test2
                                 key: 3  index: 3 name: test3

Благодаря приведенному выше четкому сравнению обнаруживается, что в дополнение к первым данным, которые можно повторно использовать, необходимо повторно отобразить остальные три данных;

Разве не удивительно, что я вставил только одну часть данных, почему все три части данных должны быть перерисованы?

Лучший способ - использовать элемент в массиве, который не изменитсяkeyЗначение соответствует элементу, то есть каждый фрагмент данных имеет уникальныйid, чтобы определить уникальность этих данных; используйтеidв видеkeyзначение, давайте сравним, как вставить кусок данных в середину, и как его отрисовать в это время

之前的数据                              之后的数据

key: 1  id: 1 index: 0 name: test1     key: 1  id: 1 index: 0  name: test1
key: 2  id: 2 index: 1 name: test2     key: 4  id: 4 index: 1  name: 我是插队的那条数据
key: 3  id: 3 index: 2 name: test3     key: 2  id: 2 index: 2  name: test2
                                       key: 3  id: 3 index: 3  name: test3

Теперь сравнение обнаруживает, что изменились только одни данные, т.е.idЧасть данных равна 4, поэтому, пока эта часть данных заново визуализируется, остальные используются повторно;

Точно так же при использовании карты для отображения списка в реакции также необходимо добавить ключ, и рекомендуется использоватьid, также по этой причине;

На самом деле, настоящая причина не в том, что случилось с vue и react, а в том, что Virtual DOM использует для реализации алгоритм Diff.

Нижеследующее примерно объясняется с точки зрения реализации алгоритма Diff виртуального DOM.

Алгоритм Diff виртуального DOM vue и react примерно одинаков, и его ядро ​​основано на двух простых предположениях:

  1. Два одинаковых компонента создают похожие структуры DOM, а разные компоненты создают разные структуры DOM.
  2. Группа узлов на одном уровне, их можно отличить по уникальному идентификатору. Основываясь на двух приведенных выше предположениях, сложность алгоритма Diff виртуального DOM снижается с O (n ^ 3) до O (n).

ЦитироватьАлгоритм сравнения ReactПример в:

diff1.jpg
Когда в слое много одинаковых узлов, то есть узлов-списков, процесс обновления алгоритма Diff также по умолчанию следует вышеуказанным принципам. Например такая ситуация:
diff2.jpg
Мы надеемся, что сможем добавить букву F между B и C. Алгоритм Diff по умолчанию выполняется следующим образом:
diff3.jpg
То есть обновление C до F, D до C, E до D и, наконец, вставка E — это неэффективно?

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

diff4.jpg

Короче говоря, функция ключа в основном заключается в эффективном обновлении виртуального DOM. Кроме того, ключевой атрибут также используется при переключении перехода элементов с одинаковым именем тега в vue.Цель также состоит в том, чтобы позволить vue различать их, иначе vue только заменит свои внутренние атрибуты, не вызывая эффекта перехода.

Ссылаться на