Предупреждение Vue на консоли: у вас может быть бесконечный цикл обновления в функции рендеринга компонента

Я новый студент факультета компьютерных наук, и у меня есть школьный проект на Vue.js. Он работает, но показывает следующее предупреждение:

[Предупреждение Vue]: у вас может быть бесконечный цикл обновления в функции рендеринга компонента.

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

Мне нужно создать фотосетку/альбом, в каждой строке которого отображается не более 3 фотографий. Что-то вроде этого: Пример того, как это должно выглядеть

Код такой:

  <template>
<v-container>
  <!-- 'v-container' est´substituindo ' div class = "clubes-lista" '-->
  <div class = "grid-photo">
    <v-container class = "grey lighten-3">
      <v-row
        v-for = "index in numberLines()"
        :key = "index"
        class = "grey lighten-3"
      >
        <v-col v-for = "n in 3" :key = "n" cols = "4">
          <v-card v-if = "numberPhotos > checkInsertedAllPhotos()" outlined>
            <v-img
              src = "https://i.pinimg.com/736x/96/28/b7/9628b7892fd0543782f53eeec4bae502.jpg"
              alt = "Bird Photo"
            >
            </v-img>
            <div class = "photo-subtitle">
              <v-icon size = "15">mdi-heart-outline</v-icon>
              <p>The Cockatiel</p>
            </div>
          </v-card>
          <v-card v-else></v-card>
        </v-col>
      </v-row>
    </v-container>
  </div>
</v-container>
<script>
export default {
name: "PhotoGrid",

data() {
  return {
    listPhotosOnGrid: [],
    numberPhotos: 0,
    numberTotalLines: 0,
    countPhotos: 0,
  };
},

computed: {},

methods: {
  createPhotosList() {
    var listPhotos = [];
    for (var i = 0; i < 10; i++) {
      var aux = {
        id: i + 1,
        src:
          "https://i.pinimg.com/736x/96/28/b7/9628b7892fd0543782f53eeec4bae502.jpg",
        subtitle: "The cockatiel",
      };

      listPhotos.push(aux);
    }

    this.listPhotosOnGrid = listPhotos;
    this.numberPhotos = listPhotos.length;
  },

  numberLines() {
    this.createPhotosList();
    var photosMultipleThree = this.numberPhotos;

    while (photosMultipleThree % 3 != 0) {
      photosMultipleThree = photosMultipleThree + 1;
    }
    this.numberTotalLines = photosMultipleThree / 3;

    return photosMultipleThree / 3;
  },

  checkInsertedAllPhotos() {
    var cont = this.countPhotos++;
    return cont;
  },
},

};

<style scoped>
.photo-subtitle {
  font-size: 10px;
  display: flex;
  flex-direction: row;
  justify-content: left;
  align-items: flex-start;
  padding: 0;
  margin-top: 10px;
}

.photo-subtitle p {
  margin-left: 5px;
}

Итак... Пытаясь понять, что происходит, я думаю, что предупреждение исходит из следующей строки:

<v-card v-if = "numberPhotos > checkInsertedAllPhotos()" outlined>

Если, потому что он не может показать больше изображений, чем дано. Например, в каждой строке отображается 3 фотографии, поэтому, если у меня нет общего количества фотографий, кратного os 3, я не хочу заполнять все столбцы в последней строке, а только те, которые необходимы для отображения всех фотографий.

Но я просто думаю, основываясь на некоторых тестах, я не уверен, исходит ли предупреждение из этой строки.

Код работает, но я чувствую, что что-то не так. (На самом деле это работает частично, потому что я до сих пор не знаю, как получить информацию из массива для отображения, поэтому он повторяет одно и то же)

Я хочу научиться делать это правильно.

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

Я просто хочу учиться.

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

:)

Прежде всего, 1. эта функция checkInsertedAllPhotos() всегда возвращает 1, потому что вы увеличиваете 1 только один раз. 2. v-for = "index in numberLines()" Здесь numberLines() является числом, потому что вы возвращаете photosMultipleThree / 3. Вы не можете перебрать число в цикле.

KienHT 10.12.2020 09:34

3. Не рекомендуется использовать v-if внутри v-for. Вместо этого, используя вычисляемые свойства, сначала фильтруйте массив, а затем перебирайте отфильтрованный массив.

KienHT 10.12.2020 09:38
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
788
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я посмотрел на ваш код. Во-первых, я бы порекомендовал вам перестать использовать ключевое слово var, а вместо этого использовать let или const (вы можете проверить вопрос здесь и взглянуть на область действия, основанную на этом ключевом слове, область действия var очень необычна в настоящее время, и это приведет к вы к некоторым вопросам).

Что касается вашей конкретной проблемы с бесконечным циклом обновления, проблема связана с вашей функцией checkInsertedAllPhotos. Я бы объяснил это так:

  • В v-if внутренние механизмы Vue проверяют, должен ли элемент отображаться, вызывая функцию checkInsertedAllPhotos

  • При выполнении функции checkInsertedAllPhotos данные countPhotos увеличиваются (кстати лучше было бы просто сделать

    this.countPhotos ++; return this.countPhotos;

  • Поскольку данные были изменены, Vue запускает повторный рендеринг страницы.

  • Поскольку происходит повторный рендеринг, Vue проверяет в v-if, должен ли элемент рендериться, вызывая функцию checkInsertedAllPhotos.

И это может быть бесконечно, если Vue не предотвратит это!

Я бы предложил немного переработать вашу логику. Однако быстрым решением вашей проблемы было бы то, что когда вы проверяете индекс в своем списке: например, если вы хотите отобразить listPhotosOnGrid[i], вы проверяете, если i<numberPhotos с помощью v-if, а в v-else вы можете отобразить что-то еще если ты хочешь.

Я также думаю, что вы могли бы иметь гораздо более простой код, используя css (например, css-grid). У вас может быть что-то простое:

<div v-for = "n in 100">
    <img v-bind:src = "`https://i.pinimg.com/photos/${n}.png`">
</div>

и некоторые css для его стилизации и имеют только 3 элемента в строке. Если вы хотите узнать о css-grid, я бы порекомендовал документацию Mozzila или следующий учебник.

Прямо сейчас у меня есть небольшая проблема с пониманием точного вопроса, так как внутри есть несколько тем для решения, но я надеюсь, что мое объяснение бесконечного цикла поможет вам!

Получайте удовольствие, изучая Vue!

Спасибо всем, кто помог мне, и вы, безусловно, помогли мне!!!!

Извините, что смог ответить только сегодня. Я думаю, что смог сделать код намного лучше, я многое изменил, особенно логику кода. И я думаю, что это может стать еще лучше, но я точно уже добился большого прогресса, хе-хе.

Я немного не хотел публиковать этот вопрос, потому что, хотя в то время, когда я его публиковал, я не знал, что делать, у меня было ощущение, что это что-то глупое (например, глупый вопрос), и что я только отнял бы время у любого, кто остановился на моем вопросе. Но я получил только удивительные ответы, все были такими терпеливыми, так что СПАСИБО ВАМ БОЛЬШОЕ!!

(Я также новичок в StackOverflow, поэтому надеюсь, что все делаю правильно, хе-хе)

Другие вопросы по теме