TypeError: Невозможно прочитать свойства неопределённого значения (чтение ‘atribute’)

Вопрос или проблема

По какой-то причине моё приложение не распознаёт один из атрибутов полученного JSON. Оно получает ‘posts’ и должно формировать ссылки на основе ‘posts.links’. Я пишу этот код:

<Link
 v-for="link in props.posts.links"
 :key="link.label"
 v-if="link.url"
 :href="link.url"
 class="px-4 py-2 rounded"
 :class="{'bg-emerald-400 text-white': link.active, 'bg-gray-200': !link.active}"
  >
  {{ link.label }}
</Link>

Но я получаю ошибку “TypeError: Невозможно прочитать свойства undefined (чтение ‘url’)”. Если написать жестко (например, posts.links[0].url), то приложение распознаёт атрибут “url”, и всё работает хорошо.

Если заменить v-if="link.url" на v-if="link !== undefined", то появляется другая ошибка: [Vue warn]: Свойство "link" было доступно во время рендеринга, но не определено в экземпляре. и страница загружается, но навигационная панель страницы не отображается.

При первом рендеринге posts.links недоступен, попробуйте добавить условное рендеринг, чтобы проверить, доступен ли он:

<template>
 <!-- ...-->
  <template v-if="posts.links">
   <Link
    v-for="link in posts.links"
    :key="link.label"
    :href="link.url"
     class="px-4 py-2 rounded"
     :class="{'bg-emerald-400 text-white': link.active, 'bg-gray-200': !link.active}"
  >
       {{ link.label }}
   </Link>

</template>

<!-- ...-->
</template>

Обратите внимание, что не следует устанавливать v-if и v-for на одном элементе, также нет необходимости ссылаться на props в шаблоне.

Ответ или решение

Ошибка TypeError: Cannot read properties of undefined (reading 'url') возникает, когда вы пытаетесь обратиться к свойству объекта, который еще не существует или не инициализирован. В вашем случае вы получаете это сообщение, когда ваш компонент пытается рендерить ссылки из posts.links, но на первом рендере данные posts.links еще недоступны.

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

<template>
  <!-- Проверяем, есть ли данные и существуют ли ссылки -->
  <template v-if="props.posts && props.posts.links">
    <Link
      v-for="link in props.posts.links"
      :key="link.label"
      v-if="link.url" <!-- Проверяем наличие url перед рендерингом ссылки -->
      :href="link.url"
      class="px-4 py-2 rounded"
      :class="{'bg-emerald-400 text-white': link.active, 'bg-gray-200': !link.active}"
    >
      {{ link.label }}
    </Link>
  </template>
</template>

Объяснение изменений:

  1. Условная проверка:

    • Мы добавили проверку v-if="props.posts && props.posts.links" для обеспечения того, что posts и posts.links существуют перед рендерингом списка ссылок. Это предотвратит попытки доступа к свойствам недоступного объекта.
  2. Отдельный шаблон для ссылок:

    • Убедитесь, что v-if и v-for не находятся на одном элементе. Соответственно, v-if помещен на обертку <template>, чтобы избежать потенциальных конфликтов и путаницы.
  3. Свойство props:

    • Для доступа к свойствам компонента нет необходимости указывать props. Достаточно использовать posts, если они переданы как свойства в компонент.

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

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

Капча загружается...