Создание адаптивных Vue компонентов с помощью ResizeObserver

Создание адаптивных Vue компонентов с помощью ResizeObserver

От автора: привет, ребята! Сегодня хочу поделиться с вами небольшой, но полезной статьей про создание компонента Vue. В моем текущем проекте у меня много многоразовых компонентов (я назвал их «виджетами»), которые можно разместить где угодно. И у меня возникла проблема с адаптивным дизайном. Наконец, я понял, что css @media запросы абсолютно не подходят под мой случай.

Так в чем проблема?

Представьте, что у нас есть компонент PostsItem . У нас есть PostsPage со списком постов:

Создание адаптивных Vue компонентов с помощью ResizeObserver

Всего несколько строк CSS, не так ли?

.post__item {
  display: flex;
}
.post__image {
  flex: 0 0 200px;
  height: 200px;
} 

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

Фреймворк VUE JS: быстрый старт, первые результаты

Получите бесплатный курс и создайте веб-приложение на трендовой Frontend-технологии VUE JS с полного нуля

Узнать подробнее

Создание адаптивных Vue компонентов с помощью ResizeObserver

Вы можете сказать «легко», @media решает эту проблему, не так ли?

@media only screen and (max-width: 576px) {
  .post__item {
 flex-direction: column;
  }
 
  .post__image {
 flex: 0 auto;
 height: auto;
  }
} 

Хорошо, способ работает. Но что, если мы будем использовать наш компонент PostsItem в другом месте?

Создание адаптивных Vue компонентов с помощью ResizeObserver

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

Итак, самая большая проблема @media запросов: «Адаптивность компонента зависит от размера экрана, а должна полагаться на собственные размеры»

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

Нам нужны локальные адаптивные стили. И здесь нам поможет ResizeObserver!

ResizeObserver

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

Фреймворк VUE JS: быстрый старт, первые результаты

Получите бесплатный курс и создайте веб-приложение на трендовой Frontend-технологии VUE JS с полного нуля

Узнать подробнее

Использовать его очень просто:

const observer = new ResizeObserver(entries => {
  entries.forEach(entry => {
 const cr = entry.contentRect;
 console.log('Element:', entry.target);
 console.log(`Element size: ${cr.width}px x ${cr.height}px`);
 console.log(`Element padding: ${cr.top}px ; ${cr.left}px`);
  })
})

observer.observe(someElement) 

Вы можете сказать, что у него плохая поддержка в браузерах:

Создание адаптивных Vue компонентов с помощью ResizeObserver

Но, к счастью, у ResizeObserver есть polyfill, основанный на MutationObserver:

Создание адаптивных Vue компонентов с помощью ResizeObserver

Использование с Vue

Я сделал небольшую обертку ResizeObserver для Vue.js (также работает на Nuxt.js ), которая позволяет легко работать с адаптивными компонентами:

<template>
  <Responsive :breakpoints="{
 small: el => el.width <= 500
  }">
 <div slot-scope="el" :class="['post__item', { small: el.is.small }]">
 <img class="post__image" :src="post.image" />
 <div class="post__text">{{post.text}}</div>
 </div>
  </Responsive>
</template>

<script>
import { Responsive } from "vue-responsive-components"
export default {
  props: ['post'],
  components: { Responsive }
}
</script>

<style lang="scss">
.post__item {
  display: flex;
}
.post__image {
  flex: 0 0 200px;
  height: 200px;
}
.post__item.small {
  flex-direction: column;
 
  .post__image {
 flex: 0 auto;
 height: auto;
  }
}
</style> 

И теперь макет выглядит отлично, даже когда мы помещаем 3 поста подряд:

Создание адаптивных Vue компонентов с помощью ResizeObserver

Теперь наш компонент действительно независим! Это также дает возможность определять другую разметку html, а не только CSS. Например, я добавил вкладки и «доп. маленькое» представление поста для небольшого блока:

Создание адаптивных Vue компонентов с помощью ResizeObserver

Кроме того, хочу отметить, что полностью удалил все @media запросы из текущего проекта в пользу ResizeObserver.

UPD: бонус: директива v-responsive

Я добавил v-responsive директиву, чтобы избавиться от компонента-оболочки:

<template>
  <!-- Will add/remove .small if the width is less / greater -->
  <div class="post__item" v-responsive="{ small: el => el.width <= 500 }">
 <img class="post__image" :src="post.image" />
 <div class="post__text">{{post.text}}</div>
  </div>
</template>

<script>
import { ResponsiveDirective } from "vue-responsive-components"
export default {
  props: ["post"],
  directives: {
 responsive: ResponsiveDirective
  }
}
</script> 

Автор: Anton Kosykh

Источник: https://itnext.io/

Редакция: Команда webformyself.

Фреймворк VUE JS: быстрый старт, первые результаты

Получите бесплатный курс и создайте веб-приложение на трендовой Frontend-технологии VUE JS с полного нуля

Узнать подробнее

Фреймворк VUE JS

VUE JS - полное руководство для современной веб-разработки

Научиться

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree