Введение в воспроизведение динамического списка в Vue.js

1656627739 vvedenie v vosproizvedenie dinamicheskogo spiska v vuejs

автор Хасан Джирде

1*smV1EYFRTT4wGha020XFIA

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

В этой статье мы разберемся с Vue v-for директива в разработке динамических списков. Мы также рассмотрим несколько примеров, почему key При этом следует использовать атрибут.

Поскольку мы будем подробно объяснять вещи, когда начинаем писать код, эта статья предусматривает, что у вас нет или очень мало знаний о Vue (и/или другие фреймворки JavaScript).

Пример: Twitter

Мы собираемся использовать Twitter в качестве примера для этой статьи.

Когда мы вошли в систему и на главном индексном маршруте Twitter, мы имеем вид, подобный этому:

0*yAgKZT2NuFjBWWbC

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

Хотя эти данные получаются динамически, способ эти показанные данные остаются постоянными. Отчасти это связано с использованием многоразовые веб-компоненты.

К примеру, мы можем увидеть список твитов как список синглов tweet-component предметов. Мы можем придумать tweet-component как оболочка, принимающая такие данные, как имя пользователя, дескриптор, твиты и аватар, среди прочих частей, и просто отображает эти фрагменты в последовательной разметке.

0*BdB3OeyWDWHuMNiN

Скажем, мы хотели бы отобразить список компонентов (например, список tweet-component элементов) на основе большого источника данных, полученных с сервера. В Vue первое, что должно приходить в голову, чтобы это сделать, это v-for директива.

Директива v-for

The v-for Директива используется для просмотра списка элементов на основе источника данных. Директиву можно использовать в элементе шаблона и требует определенного синтаксиса, например:

0*Z1iUt5OO46Ari1uK

Увидим это на примере на практике. Во-первых, мы предположим, что мы уже получили коллекцию данных твитов:

const tweets = [
  {
    id: 1,
    name: 'James',
    handle: '@jokerjames',
    img: '
    tweet: "If you don't succeed, dust yourself off and try again.",
    likes: 10,
  },
  { 
    id: 2,
    name: 'Fatima',
    handle: '@fantasticfatima',
    img: '
    tweet: 'Better late than never but never late is better.',
    likes: 12,
  },
  {
    id: 3,
    name: 'Xin',
    handle: '@xeroxin',
    img: '
    tweet: 'Beauty in the struggle, ugliness in the success.',
    likes: 18,
  }
]

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

Прежде всего, мы создадим экземпляр Vue – сердце программы Vue. Мы смонтируем/присоединим наш экземпляр к элементу DOM с идентификатором appи назначить tweets коллекция как часть объекта данных экземпляра.

new Vue({
  el: '#app',
  data: {
    tweets
  }
});

Теперь мы продолжим создавать a tweet-component что наша v-forДиректива будет использоваться для просмотра списка. Мы будем использовать глобальный Vue.componentконструктор для создания компонента с именем tweet-component:

Vue.component('tweet-component', {
  template: `  
    <div class="tweet">
      <div class="box">
        <article class="media">
          <div class="media-left">
            <figure class="image is-64x64">
              <img :src=" alt="Image">
            </figure>
          </div>
          <div class="media-content">
            <div class="content">
              <p>
                <strong>{{tweet.name}}</strong> <small>{{tweet.handle}}</small>
                <br>
                {{tweet.tweet}}
              </p>
            </div>
              <div class="level-left">
                <a class="level-item">
                  <span class="icon is-small"><i class="fas fa-heart"></i></span>
                  <span class="likes">{{tweet.likes}}</span>
                </a>
              </div>
          </div>
        </article>
      </div>
    </div>  
  `,
  props: {
    tweet: Object
  }
});

Здесь стоит обратить внимание на несколько интересных вещей:

  1. The tweet-component ожидает а tweet объект опорный, как показано в требовании проверки prop (props: {tweet: Object}). Если компонент отображается с помощью a tweet опора, то есть не объектVue будет выдавать предупреждение.
  2. Мы привязываем свойства объекта твита к шаблону компонента с помощью синтаксиса Mustache: {{ }}.
  3. Разметка компонента адаптирует элемент Bulma’s Box, поскольку он очень похож на твит.

В шаблоне HTML нужно создать разметку, куда будет смонтирована наша программа Vue (т.е. элемент с идентификатором) app). В рамках этой разметки мы будем использовать v-for директива для воспроизведения списка твитов.

Так как tweets это сбор данных, который мы будем повторять, tweet будет подходящим псевдонимом для использования в директиве. В каждом нанесенном tweet-componentНу также перейти в повторенный tweet объект в качестве реквизита для доступа к нему в компоненте.

<div id="app" class="columns">
  <div class="column">
    <tweet-component v-for="tweet in tweets" :tweet="tweet"/>
  </div>
</div>

Независимо от как многое больше объектов твитов будет введено в коллекцию или то, как они будут меняться со временем — наши настройки всегда будут отображать все твиты в коллекции в той же разметке, которую мы ожидаем.

С помощью специального CSS наше приложение будет выглядеть примерно так:

Смотрите фильм Pen Simple Twitter №1 от Hassan Dj (@itslit) на CodePen.

Хотя все работает, как ожидалось, нам может быть предложена подсказка Vue на консоли браузера:

[Vue tip]: <tweet-component v-for="tweet in tweets">: component lists rendered with v-for should have explicit keys...

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

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

Ключевой атрибут

Обычной практикой является указывать ключевой атрибут для каждого повторяющегося элемента в обработанном изображении v-for список. Это потому, что Vue использует key атрибут для создания уникальные привязки для идентификации каждого узла.

Объясним это еще немного — если в нашем списке были какие-то динамические изменения пользовательского интерфейса (например, порядок элементов списка перемешивается), Vue выберет изменение данных в каждом элементе вместо этого перемещение элементов DOM соответственно. В большинстве случаев это не станет проблемой. Однако в определенных случаях, когда наша v-for список зависит от состояния DOM и/или состояния дочернего компонента, это может привести к нежелательному поведению.

Давайте посмотрим на пример этого. Что если наш простой компонент твита теперь содержал поле ввода, которое позволит пользователю непосредственно ответить на сообщение твита? Мы игнорируем, как можно отправить этот ответ, и просто обратимся к самому новому полю ввода:

0*X3dVBOFq76PJQFGC

Мы включим это новое поле ввода в шаблон tweet-component:

Vue.component('tweet-component', {
  template: `
    <div class="tweet">
      <div class="box">
        // ...
      </div>
      <div class="control has-icons-left has-icons-right">
        <input class="input is-small" placeholder="Tweet your reply..." />
        <span class="icon is-small is-left">
          <i class="fas fa-envelope"></i>
        </span>
      </div>
    </div>
  `,
  props: {
    tweet: Object
  }
});

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

Для этого мы можем сначала включить Shuffle! кнопку в нашем шаблоне HTML:

<div id="app" class="columns">
  <div class="column">
    <button class="is-primary button" @click="shuffle">
      Shuffle!
    </button>
    <tweet-component v-for="tweet in tweets" :tweet="tweet"/>
  </div>
</div>

Мы присоединили прослушиватель события клика к элементу кнопки, чтобы вызвать a shuffle метод при запуске В нашем экземпляре Vue мы создадим файл shuffle метод, отвечающий за случайное перемешивание tweets сбор в экземпляре. Для достижения этого мы будем использовать метод _shuffle lodash:

new Vue({
  el: '#app',
  data: {
    tweets
  },
  methods: {
    shuffle() {
      this.tweets = _.shuffle(this.tweets)
    }
  }
});

Давайте попробуем! Если мы несколько раз нажмем перемешать, мы заметим, что наши элементы твитов будут случайным образом сортироваться с каждым щелчком.

Просмотрите ленту Pen Simple Twitter №2 от Hassan Dj (@itslit) на CodePen.

Однако если мы введем некоторую информацию во входные данные каждого компонента и потом щелкните перемешивать, мы заметим, что происходит что-то необычное:

1*1PN7mevBsMNhS03dt6-7qA

Поскольку мы не решили использовать key Vue не создал уникальные привязки к каждому узлу твитов. В результате, когда мы стремимся изменить порядок твитов, Vue использует более эффективный подход к сохранению, чтобы просто изменить (или патч) данные по каждому элементу. Поскольку временное состояние DOM (т.е. введенный текст) остается на месте, мы чувствуем это непреднамеренное несоответствие.

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

1*IKwgNEwHYMwzRq8nOiBjog

Чтобы избежать этого; нам придется назначить уникальный ключ каждому tweet-componentпредставлены в списке.

Мы будем использовать id а tweet быть уникальным идентификатором, поскольку мы должны безопасно сказать твит id не должно быть равно другим. Поскольку мы используем динамические значения, мы будем использовать v-bind директиву, чтобы привязать наш ключ к tweet.id:

<div id="app" class="columns">
  <div class="column">
    <button class="is-primary button" @click="shuffle">
      Shuffle!
    </button>
    <tweet-component
      v-for="tweet in tweets"
      :tweet="tweet"
      :key="tweet.id"
    />
  </div>
</div>

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

1*GXx_K3xLDHF8PZRTILoW_Q

Переходы

Поскольку каждый компонент твита теперь перемещается соответствующим образом, мы можем шагнуть дальше и использовать Vue transition-group к показать как изменяется порядок частей.

Для этого мы добавим transition-group элемент как обертка до v-for список. Мы укажем название перехода tweets и объявляют, что группа перехода должна быть представлена ​​как a div элемент.

<div id="app" class="columns">
  <div class="column">
    <button class="is-primary button" @click="shuffle">
      Shuffle!
    </button>
    <transition-group name="tweets" tag="div">
      <tweet-component
         v-for="tweet in tweets"
         :tweet="tweet"
         :key="tweet.id"
      />
    </transition-group>
  </div>
</div>

На основе названия перехода Vue автоматически распознает, были ли указаны переходы/анимации CSS. Поскольку мы стремимся вызвать переход для движение элементов в списке, Vue будет искать указанный переход CSS вдоль строк tweets-move (где tweets это название, данное нашей переходной группе).

В результате мы вручную введем a .tweets-move класс, имеющий указанный тип и время перехода:

#app .tweets-move {
  transition: transform 1s;
}

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

Наши tweet-component элементы будут сейчас перехода соответствующим образом между локациями, когда вызывается перемешивание. Попробуй! Введите некоторую информацию в поле ввода и нажмите «Shuffle!» несколько раз.

Достаточно круто, правда? Без key атрибут, элемент Transmission-group нельзя использовать для создания переходов списка поскольку элементы есть залатан на месте вместо того, чтобы быть переупорядоченным.

Следует ли key атрибут всегда использоваться? Это рекомендовано. В документах Vue указано, что атрибут key следует опускать только в следующих случаях:

  • Мы намеренно хотим, чтобы из соображений производительности использовался способ исправления элементов по умолчанию.
  • Содержимое DOM достаточно простое.

Вывод

И вот у нас! Надеюсь, эта краткая статья показала, насколько полезным v-for директива, а также предоставлено немного больше контекста, чем key атрибут часто используется. Дайте мне знать, если у вас могут возникнуть вопросы/мысли!

Если вам понравился мой стиль письма и вы потенциально заинтересованы в том, чтобы научиться создавать реальные программы с помощью Vue, вам понравится книга Fullstack Vue: Полное руководство по Vue.js что я помог опубликовать! Книга охватывает многочисленные аспекты Vue, включая маршрутизацию, простое управление состоянием, обработку форм, Vuex, сохранение сервера и тестирование среди других тем. Если вы заинтересованы и/или хотите попробовать образец раздела, вы можете получить дополнительную информацию на нашем веб-сайте https://fullstack.io/vue!

Если у вас возникнут вопросы/мысли/мысли, вы можете связаться со мной в любое время @djirdehh!

Добавить комментарий

Ваш адрес email не будет опубликован.