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

Nuxt.js: универсальные приложения Javascript для всех

Вдохновленный Next.js Zeit, Nuxt - это фреймворк, построенный на основе Vue.js для создания универсальных веб-приложений, которые работают как одностраничные приложения, рендеринг на стороне сервера или как статический веб-сайт. У него самоуверенный дизайн, который структурирует Vue и устраняет некоторые сложности, связанные с запуском вашего веб-сайта на сервере. Часть кода выполняется на стороне сервера, а часть - на стороне клиента. Masonry необходимо запускать на стороне клиента, и у Nuxt есть способы с этим справиться.

Установка кладки

Я пошел дальше и установил Masonry и ImagesLoaded в свои модули Node. В документации по Masonry показано, как установить его с помощью npm или yarn, но не показано, как импортировать его в свой код.

yarn add masonry-layout imagesloaded

Нет SSR, нет проблем!

В документации Nuxt.js показано, как загрузить плагин и установить для него логическое значение NoSSR, но у меня это не сработало. Nuxt нужен способ узнать, что этот скрипт загружается только на стороне клиента. В их разделе часто задаваемых вопросов есть фрагмент, который можно использовать, используя переменную process.browser и синтаксис ES5 require вместо импорта ES6.

if (process.browser) {
var Masonry = require(“masonry-layout”);
var ImagesLoaded = require(“imagesloaded”);
}

Если вы используете сценарии на нескольких страницах, разумно добавить их в пакет вашего поставщика в файле nuxt.config.js.

build: {     
vendor: ['external_library']   
}

Настройка параметра Masonry с использованием объекта данных Vue

Нам нужно настроить параметры Masonry, и мы можем использовать наш объект данных в Nuxt, чтобы позаботиться об этом. Все варианты масонства доступны в объекте настроек.

data() {
 return {
  selector: ".viewer",
  options: {
   columnWidth: ".grid-sizer",
   percentPosition: true,
   gutter: 0,
   itemSelector: ".item"
  }
 };
}

Инициализация Masonry в эмиттере событий Vue

Создайте метод загрузки Masonry, я назвал его loaded (). ImagesLoaded гарантирует, что все изображения в наших элементах макета сетки загружены, прежде чем организовывать и размещать все. После загрузки Masonry генерируется событие Vue с функцией Masonry в качестве полезной нагрузки.

methods: {
loaded() {
// all images are loaded
ImagesLoaded(this.selector, () => {
this.$emit("masonry-images-loaded");
// activate mansonry grid
let masonry = new Masonry(this.selector, this.options);
this.$emit("masonry-loaded", masonry);
});
}...

Затем метод загружается в подключенный обработчик жизненного цикла или при изменении данных.

watch: {
data() {
this.loaded();
}
},
mounted() {
this.loaded();
},

HTML и CSS шаблоны

Мой код шаблона HTML выглядит примерно так, ваш может отличаться. Класс .viewer - это оболочка Masonry, .grid-sizer устанавливает наименьшую ширину сетки, а .item - каждый элемент сетки. .box-0 отображается в два раза шире, чем другие элементы сетки.

<div class="viewer m-2 mt-3 mt-5 m-md-5">
<div class="grid-sizer"></div>
<div v-for="(image, index) in worksingle.Images" :data-index="index" :key="index" :class="`box-${index}`" class="item">
<img class="work-thumb" sizes="100vw" :src="image.path">
<div v-if="image.meta.title" :style="`color:#${getImgColor(image.meta.asset)};`" class="working-desc small">{{image.meta.title}}</div>
</div>
</div>

Наконец, немного CSS для стилизации макета сетки.

@media only screen and (max-width: 768px) {
.grid-sizer {
width: 100%;
}
.item {
width: 100%;
padding-bottom: 10px;
padding-left: 0px;
}
.box-0 {
width: 100%;
}
}
@media only screen and (min-width: 769px) {
.grid-sizer {
width: 33%;
}
.item {
width: 33%;
padding-bottom: 10px;
padding-left: 10px;
}
.box-0 {
width: 66%;
}
}
@media only screen and (min-width: 1200px) {
.grid-sizer {
width: 25%;
}
.item {
width: 25%;
padding-bottom: 10px;
padding-left: 10px;
}
.box-0 {
width: 50%;
}
}

Заключение

Заставить Masonry и другие библиотеки Javascript для пользовательского интерфейса, макета и анимации работать в Nuxt может быть немного сложно, но использование переменной process.browser, ES5 требует синтаксиса и эмиттера событий Vue может помочь.

Посетите мое портфолио на jake101.com и прокомментируйте любые советы или рекомендации по работе с Nuxt.