Экран загрузки скелета Vue с использованием неизвестных компонентов - Daily Vue # 4

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

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

В Vue3 введение компонентов саспенса упростило добавление скелетных загрузчиков.

В этом примере я воссоздал Средний авторский раздел, используя асинхронный компонент, загрузчик скелета и новые компоненты саспенса Vue.

Вот быстрый скриншот того, что мы будем строить!

В восторге? Я тоже - давайте прямо сейчас.

Как будет работать наш экран загрузки скелета?

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

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

Затем мы создадим второй компонент, который отображает скелет нашего информационного компонента пользователя. Мы сделаем это, просто создавая блоки разного размера для представления разных разделов.

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

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

Создание нашей ProfileCard

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

Поскольку это асинхронный компонент, нам нужно сделать наш метод настройки асинхронным. Мы также хотим создать еще один асинхронный метод, который загружает данные нашего профиля с использованием setTimeout в демонстрационных целях.

import { ref } from 'vue' 

const loadUserData = async () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({
        name: 'Matt Maribojoc',
        pic: 'https://cdn-images-1.medium.com/fit/c/100/100/2*EcZb9cndrhTF7_d74dv2Fg.png',
        bio: 'I run a VueJS community over at https://learnvue.co, develop web sites, and post whatever I find cool on the Internet.'
      })
    }, 4000)
  })
}

export default {
  async setup () {
    const userData = ref(await loadUserData())
    
    return {
      userData
    }
  }
}

Если вам это кажется совершенно запутанным, ознакомьтесь с нашим руководством по Composition API.

Давайте представим наш шаблон. Это код, который я использовал, и вот несколько ссылок на изображение границы.

<template>
  <div class='profile-card'>
    <div class='profile-image'>
      <img class='profile-image__border' src='../assets/img-border.png' />
      <img class='profile-image__img' :src='userData.pic' />
    </div>
    <div class='profile-info'> 
      <span> Written By </span>
      <h3> {{ userData.name }} </h3>
      <p> {{ userData.bio }} </p>
    </div>
  </div>
</template>

Наконец, давайте стилизуем его, чтобы он выглядел красиво. Это те стили, которые я использовал.

<style>  
  .profile-card {
    width: 100%;
    max-width: 700px;
    margin: 0 auto;
    padding: 30px;
    box-sizing: border-box;
    border-radius: 20px;
    background-color: #fff;
    overflow: hidden;
    position: relative;
    min-height: 150px;
  }

  .profile-card .profile-image__img {
    width: 10%;
    height: auto;
    border-radius: 50%;
    position: absolute;
    top: 30px;
    left: 30px;
  }

  .profile-card .profile-image__border {
    width: calc(10% + 20px);
    height: auto;
    position: absolute;
    top: 20px;
    left: 20px;
  }

  .profile-info {
    width: 85%;
    float: right;
    padding-left: 10px;
    box-sizing: border-box;
  }

  .profile-info span {
    text-transform: uppercase;
    color: #666;
    letter-spacing: 3px;
  }

  .profile-info h3 { 
    margin: 10px 0;
    font-weight: 700;
    font-size: 1.5em;
    color: #222;
  }

  .profile-info p {
    line-height: 140%;
    color: #666;
  }
</style>

Теперь наш компонент ProfileCard должен выглядеть так.

Использование приостановленных компонентов для отрисовки резервного содержимого

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

Внутри какого-то другого компонента мы можем использовать этот код для создания нашего компонента саспенса.

<Suspense>
      <template #default>
        <profile-card />
      </template>
      <template #fallback>
        Loading...
      </template>
</Suspense>

Теперь, если мы запустим наше приложение, мы увидим, что оно говорит Loading… в течение нескольких секунд, пока наш компонент ProfileCard не разрешится.

Но это не экран загрузки скелета! Итак, давайте построим это прямо сейчас.

Создание нашего загрузочного экрана скелета

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

Мы будем повторно использовать некоторые стили макета, чтобы гарантировать, что наш скелет имеет тот же контур, что и наш фактический компонент. Поскольку мы не ограничивали наши стили областью видимости в компоненте ProfileCard, они также автоматически стилизуют наш компонент ProfileCardSkeleton.

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

<div class='profile-card'>
    <div class='profile-image'>
      <img class='profile-image__border' src='../assets/img-border.png' />
      <img class='profile-image__img' />
    </div>
    <div class='profile-info'> 
      <span />
      <h3 />
      <p />
    </div>
  </div>

Затем нам остается только добавить несколько стилей с заданной областью, чтобы добавить тот серый фон, который мы ищем.

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

Для этого мы просто даем каждому отдельную высоту, ширину и цвет фона.

<style scoped>
.profile-card .profile-image__img {
    width: 10%;
    padding-top: 10%;
    border-radius: 50%;
    background-color: #ddd;
  }

  .profile-info span {
    min-width: 100px;
    height: 16px;
    display: inline-block;
    background-color: #ddd;
  }

  .profile-info h3 {
    content: ' ';
    width: 250px;
    height: 24px;
    background-color: #ddd;
    margin: 10px 0;
  }

  .profile-info p {
    width: 80%;
    background-color: #ddd;
    height: 16px;
    line-height: 140%;
  }
</style>

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

Чтобы добавить этот скелетный компонент в наш проект, мы можем заменить резервный контент неизвестности нашим новым компонентом.

<Suspense>
      <template #default>
        <profile-card />
      </template>
      <template #fallback>
        <profile-card-skeleton />
      </template>
    </Suspense>

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

Дополнительные функции, которые мы можем добавить

Итак, теперь, когда мы создали скелет экрана загрузки - есть много способов дополнить эту концепцию. Мы могли бы,

  • Создавайте повторно используемые скелетные компоненты для изображений, заголовков, абзацев и т. Д.
  • Добавьте больше стилей, чтобы сделать его более отзывчивым
  • Создавайте каркасные загрузчики для большего количества компонентов

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

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

Сделаем это с помощью CSS-анимации.

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

@keyframes pulse-bg {
    0% { background-color: #ddd; }
    50% { background-color: #d0d0d0; }
    100% { background-color: #ddd; }
  }

Затем внутри каждого из наших элементов мы хотим заменить свойство background-color нашей новой анимацией. Мы можем сделать это вот так.

.profile-card .profile-image__img {
    width: 10%;
    padding-top: 10%;
    border-radius: 50%;
    animation: pulse-bg 1s infinite;
  }

Конечный результат - очень тонкий штрих, но именно такие мелочи действительно могут выделить ваше приложение Vue.

И вот так!

Теперь у нас есть действительно хороший скелетный загрузчик, использующий новую функцию саспенса Vue3.

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

Я надеюсь, что это руководство помогло вам дать некоторые идеи, и, как всегда, если у вас есть какие-либо вопросы, просто дайте мне знать в ответах!

Если вы хотите узнать больше о Vue 3, скачайте мою бесплатную шпаргалку по Vue 3 с такими важными знаниями, как Composition API, синтаксис шаблона Vue 3 и обработка событий.

Примечание из JavaScript на простом английском:

Мы запустили три новых издания! Проявите любовь к нашим новым публикациям, подписавшись на них: AI на простом английском, UX на простом английском, Python на простом английском - спасибо и продолжайте учиться!