впервые опубликовано вличный блог
ключ в 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 примерно одинаков, и его ядро основано на двух простых предположениях:
- Два одинаковых компонента создают похожие структуры DOM, а разные компоненты создают разные структуры DOM.
- Группа узлов на одном уровне, их можно отличить по уникальному идентификатору. Основываясь на двух приведенных выше предположениях, сложность алгоритма Diff виртуального DOM снижается с O (n ^ 3) до O (n).
ЦитироватьАлгоритм сравнения ReactПример в:
Следовательно, нам нужно использовать ключ, чтобы сделать уникальную идентификацию для каждого узла, и алгоритм Diff может правильно идентифицировать узел и найти правильную область местоположения для вставки нового узла.
Короче говоря, функция ключа в основном заключается в эффективном обновлении виртуального DOM. Кроме того, ключевой атрибут также используется при переключении перехода элементов с одинаковым именем тега в vue.Цель также состоит в том, чтобы позволить vue различать их, иначе vue только заменит свои внутренние атрибуты, не вызывая эффекта перехода.