Найти в Дзене
in9var

Создаем крутой лендинг сайт с нуля: верстаем каталог товаров #8

Наиболее сложная секция нашего лендинга — это Catalogue, сегодня мы ей и займемся. Погнали! Полезные ссылки: Часть 1. Подготовка и настройка проекта Часть 2. Настройка конфигурации и установка необходимых библиотек Часть 3. Создание CSS-переменных и верстка блока Header Часть 4. Верстка секции Hero, создание компонента Button Часть 5. Верстка секции About Часть 6. Верстка секции Gallery Часть 7. Верстка секции WhyUs Часть 8. Верстка секции Catalogue Часть 9. Верстка секции Map Часть 10. Верстка секции Footer Часть 11. Создание якорных ссылок, рефакторинг Часть 12. Создание мобильного меню Часть 13. Анимация секций при скролле Часть 14. Установка метаданных Часть 15. Настройка Favicon.ico Часть 16. Настройка счетчика Яндекс Метрики Часть 17. Публикуем проект на хостинге Я создал подпапку items в папке images для хранения изображений товаров, в данном случае домов. В папку items загрузите любые понравившиеся вам 8 изображений с соотношением сторон 4:3. Можете взять изображения прямо из
Оглавление

Наиболее сложная секция нашего лендинга — это Catalogue, сегодня мы ей и займемся. Погнали!

Превью | Канал dzen.ru/in9var
Превью | Канал dzen.ru/in9var

Полезные ссылки:

Часть 1. Подготовка и настройка проекта

Часть 2. Настройка конфигурации и установка необходимых библиотек

Часть 3. Создание CSS-переменных и верстка блока Header

Часть 4. Верстка секции Hero, создание компонента Button

Часть 5. Верстка секции About

Часть 6. Верстка секции Gallery

Часть 7. Верстка секции WhyUs

Часть 8. Верстка секции Catalogue

Часть 9. Верстка секции Map

Часть 10. Верстка секции Footer

Часть 11. Создание якорных ссылок, рефакторинг

Часть 12. Создание мобильного меню

Часть 13. Анимация секций при скролле

Часть 14. Установка метаданных

Часть 15. Настройка Favicon.ico

Часть 16. Настройка счетчика Яндекс Метрики

Часть 17. Публикуем проект на хостинге

  • Демо–проект лендинга можно посмотреть по ссылке.
  • Шаблон лендинга, который мы будем делать, доступен в Figma по ссылке.
  • Код данного урока доступен в репозитории GitHub по ссылке.
  • В моём блоге этот урок в удобном для чтения виде по ссылке.

Подготовка изображений

Я создал подпапку items в папке images для хранения изображений товаров, в данном случае домов.

В папку items загрузите любые понравившиеся вам 8 изображений с соотношением сторон 4:3.

Можете взять изображения прямо из шаблона.

Присвоим изображениям имена ( item-01.jpg...item-08.jpg ).

Хардкодим "базу данных"

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

Создаем файл cardItems.js в папке app.

Содержимое файла cardItems.js

import image01 from '@/app/images/items/item-01.jpg';
import image02 from '@/app/images/items/item-02.jpg';
import image03 from '@/app/images/items/item-03.jpg';
import image04 from '@/app/images/items/item-04.jpg';
import image05 from '@/app/images/items/item-05.jpg';
import image06 from '@/app/images/items/item-06.jpg';
import image07 from '@/app/images/items/item-07.jpg';
import image08 from '@/app/images/items/item-08.jpg';
export const cardItems = [
{
title: 'Престиж',
area: 124,
floors: 2,
bedrooms: 3,
material: 'Брус',
price: 6960000,
src: image01.src,
},
{
title: 'Люкс',
area: 225,
floors: 2,
bedrooms: 3,
material: 'Газобетон',
price: 12860000,
src: image02.src,
},
{
title: 'Гламур',
area: 125,
floors: 1,
bedrooms: 3,
material: 'Кирпич',
price: 5600000,
src: image03.src,
},
{
title: 'Эстетика',
area: 425,
floors: 2,
bedrooms: 3,
material: 'Брус',
price: 61960000,
src: image04.src,
},
{
title: 'Аристократ',
area: 112,
floors: 1,
bedrooms: 1,
material: 'Брус',
price: 6800000,
src: image05.src,
},
{
title: 'Классика',
area: 145,
floors: 2,
bedrooms: 2,
material: 'Брус',
price: 7000000,
src: image06.src,
},
{
title: 'Экселенс',
area: 210,
floors: 2,
bedrooms: 3,
material: 'Брус',
price: 16320000,
src: image07.src,
},
{
title: 'Шарм',
area: 180,
floors: 2,
bedrooms: 2,
material: 'Брус',
price: 12000000,
src: image08.src,
},
];

Мы просто импортируем изображения и создаем объект с парами ключ:значение для каждого дома. Этот массив мы сможем использовать в нашем компоненте Catalogue.jsx.

Создание компонента Catalogue.jsx

В папке sections создадим файл компонента Catalogue.jsx.

Содержимое файла Catalogue.jsx

import ExportedImage from 'next-image-export-optimizer';
import { cardItems } from '@/app/cardItems';
export default function Catalogue() {
return (
<section className='w-full px-5 mx-auto max-w-screen-xl py-12 lg:py-32'>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-14 lg:gap-10 w-full'>
{cardItems.map((item, index) => (
<div key={index} className='flex flex-col gap-5'>
<div className={`aspect-[4/3] overflow-hidden relative`}>
<ExportedImage
alt={'card image'}
src={item.src}
fill
loading='lazy'
placeholder='blur'
className={`object-cover`}
/>
</div>
<div className='flex flex-col gap-3'>
<h3 className='text-xl font-black'>{item.title}</h3>
<div className='flex justify-between'>
<div className='flex flex-col gap-3'>
<span className='font-black'>
<span className='font-light '>Площадь: </span>
{item.area}&nbsp;м²
</span>
<span className='font-black'>
<span className='font-light '>Этажи: </span>
{item.floors}
</span>
</div>
<div className='flex flex-col gap-3 items-end'>
<span className='font-black'>
<span className='font-light '>Спальни: </span>
{item.bedrooms}
</span>
<span className='font-light '> {item.material}</span>
</div>
</div>
<span className='text-xl font-black'>
{`${item.price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ')} ₽`}
</span>
</div>
</div>
))}
</div>
</section>
);
}

В этой верстке блоки будут адаптивными, и количество колонок будет меняться от 1 до 4 в зависимости от разрешения экрана.

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

Наиболее интересен для нас кусок кода — {{cardItems.map((item, index) => (...))}}. Здесь мы проходимся по созданному массиву и в зависимости от количества элементов массива «рисуем» карточку товара, для каждого элемента свою, но используем всего 1 шаблон.

Строка с обработкой цены кажется странной для новичков ({{`${item.price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ')} ₽`}}), но не пугайтесь, я просто благодаря регулярным выражениям разбиваю число по 3 знака и вставляю между ними пробел, так ценник выглядит более читабельным.

Подключение секции к шаблону

В фале page.jsx подключим нашу новую секцию

Содержимое файла page.jsx

import About from './components/sections/About';
import Catalogue from './components/sections/Catalogue';
import Gallery from './components/sections/Gallery';
import Hero from './components/sections/Hero';
import WhyUs from './components/sections/WhyUs';
export default function Home() {
return (
<main>
<Hero />
<About />
<Gallery />
<WhyUs />
<Catalogue />
</main>
);
}

В dev-режиме, мы получим вот такой блок нашего сайта:

-2
-3

На сегодня всё!

В следующей статье мы сверстаем интерактивную секцию Map и сделаем это с помощью яндекс карт.

Код данного урока доступен в репозитории GitHub по ссылке.

Не забудь подписаться на канал, а также заходи на мой блог blog.in9var.ru, а также можешь посетить мой основной сайт — in9var.ru.