Создаем лендинг сайт с нуля: верстаем каталог товаров #8
Наиболее сложная секция нашего лендинга — это Catalogue, сегодня мы ей и займемся
Полезные ссылки:
- Шаблон лендинга, который мы будем делать, доступен в 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} м²
</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 знака и вставляю между ними пробел, так ценник выглядит более читабельным.
В dev-режиме, мы получим вот такой блок нашего сайта:
На сегодня всё!
В следующей статье мы сверстаем секцию Map.
Код данного урока доступен в репозитории GitHub по ссылке.
На этом всё, добавляйте сайт в избранное, чтобы не пропустить новых статей, а также подписывайтесь на мой Дзен-канал – dzen.ru/in9var