Быстро, кратко, скажите роль V-для цикла в Vue

Vue.js
Быстро, кратко, скажите роль V-для цикла в Vue

резюме

Что касается ключевого вопроса в v-for, на самом деле это очень распространенный вопрос. В основном используется много онлайн-поисков, и его часто задают во время интервью. Говоря об этом вопросе, вы можете создавать DOM и виртуальный DOM. , и очень важноDiffалгоритм.портал

роль (главное событие)

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

Итак, вот вопрос, дляv-forоказанныйсписокС точки зрения данных, объем данных может быть вообще огромным, и нам часто нужно выполнять некоторые добавления, удаления и модификации этих данных. Допустим, мы добавляем в список часть данных, и весь список приходится перерисовывать, что не очень хлопотно.

а такжеkeyВнешний вид должен максимально избежать этой проблемы и повысить эффективность.Если мы добавим часть данных в список, а страница только отрисовывает эти данные, она не будет идеальной.

v-forПо умолчанию используется стратегия повторного использования на месте. Когда данные списка изменены, он будет судить, изменено ли значение в соответствии со значением ключа. Если он изменен, он повторно отобразит этот элемент, в противном случае предыдущий элемент будет повторно использован.

Мы часто используем индекс (то есть индекс массива) в качестве ключа, но использовать его не рекомендуется. Например:

list = [
    {
        id: 1,
        num: 1
    },
    {
        id: 2,
        num: 2
    },
    {
        id: 3,
        num: 3
    },
];

<div v-for="(item, index) in list" :key="index">{{item.num}}</div>

В приведенном выше случае мы использовали индекс в качестве ключа.

1. Добавить часть данных после массива

list = [
    {
        id: 1,
        num: '1'
    },
    {
        id: 2,
        num: 2
    },
    {
        id: 3,
        num: 3
    },
    {
        id: 4,
        num: '新增加的数据4'
    }
];

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

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

list = [
    {
        id: 3, 
        num: 1
    },
    {
        id: 4, 
        num: '新增加的数据4'
    },
    {
        id: 2, 
        num: '2'
    },
    {
        id: 3, 
        num: '3'
    }
];

Когда страница отображает данные, путем сравнения ключей, определенных индексом, будет:

      之前的数据                    之后的数据

key: 0  index: 0 num: 1     key: 0  index: 0 num: 1
key: 1  index: 1 num: 2     key: 1  index: 1 num: '新增加的数据4'
key: 2  index: 2 num: 3     key: 2  index: 2 num: 2
                            key: 3  index: 3 num: 3

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

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

Лучший способ — использовать элемент в массиве, который не изменится, в качестве значения ключа, соответствующего элементу, то есть каждый фрагмент данных имеет уникальный идентификатор для идентификации уникальности этого фрагмента данных. Используя id в качестве значения ключа, сравним и вставим в середину кусок данных, как мы будем его рендерить в этот раз? Например:

list = [
    {
        id: 1,
        num: 1
    },
    {
        id: 4,
        num: '新增加的数据4'
    },
    {
        id: 2,
        num: 2
    },
    {
        id: 3,
        num: 3
    }
];
         之前的数据                               之后的数据

key: 1  id: 1  index: 0 num: 1     key: 1  id: 1  index: 0 num: 1
key: 2  id: 2  index: 1 num: 2     key: 4  id: 4  index: 1 num: '新增加的数据4'
key: 3  id: 3  index: 2 num: 3     key: 2  id: 2  index: 2 num: 2
                                   key: 3  id: 3  index: 3 num: 3

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

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

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

оDiffКраткий анализ

(1) Когда данные страницы изменяются, алгоритм Diff будет сравнивать только узлы на одном уровне. (2) Если типы узлов разные, сразу уничтожьте предыдущий узел, затем создайте и вставьте новый узел, и дочерние узлы этого узла не будут сравниваться. (3) Если типы узлов совпадают, свойства узла будут сброшены для реализации обновления узла.

1572254311679-ae7e030e-31f3-4e74-96ed-8b41b16009e7.png

Например

Вставляем часть данных в список:

1572254712361-ea2ed2e9-fda3-45eb-8978-6f7fa9dc0003.png

DiffАлгоритм по умолчанию такой:

1572254875830-4a912b39-28e0-4d9d-bea9-6df0c936ec3d.png

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