В этой части сделаем две очень важные секции - секция вывода цены и локации.
Задачу разделим на два этапа. На первом этапе создадим секцию цен. Это довольно простая задача, но есть одно но.
Если посмотреть на картинку, то все выглядит довольно просто. У нас есть три блока, которые находятся внутри секции. Каждый блок имеет свои значения цены, описания, позиции и главное, то чего вы не видите на статической картинке - нам нужно выводить блоки с последовательным проявлением. Вначале должен показаться блок. который по центру и после задержки в пол сек. уже первый и третий блоки.
Кнопки, мы уже создали отдельный компонент
Задачу можно решить разными путями. Я решил все это создать в одном компоненте. Данные можно передать в этот компонент извне, но так как мы можем их сохранять в самом компоненте. то это еще одно упрощение задачи. Данные можно сохранить в виде отдельных массивов (массив - цен, описаний, и пр.), тогда мы сможем их выводить в нужном порядке используя индекс в одном переборе (
В данном случае способ вывода в консоль значения не имеет. Главное что омы получаем таким образом доступ к нужным данным, которые все равно, мы будем выводить в
Второй вариант - это (обычный) сделать один массив данным с отдельными объектами - в виде каждого блока. У каждого объекта будут ключи - поля (name, price, description, position, link, delay). Вы можете выбрать любой вариант,который вам больше нравится. Главное. что в любом случае у нас будет возможность задать нужную задержку выполнения появления блока -
Способ хранения данных (внутри отдельного компонента или во внешнем файле) для нас сейчас значения не имеет, но стоит обратить внимание на то как вы храните эти значения. Я встречал сохранение статических данных в
Создадим отдельную папку и индексовый файл для нашего компонента в папке компонентов. Как мы и договорились, это будет компонент без состояния. Сразу же подключим и выведем его в файле App.js
Для Components/Pricing/index.js
Убедились, что все работает. Слева внизу появится в браузере слово - Pricing.
Теперь внутри нашего компонента создадим общую разметку для вывода трех блоков - выше в коде красным. Добавляем слили
recourses/style.css
После этого в браузере мы увидим наше слово выеденное один раз.
Данные я решил собрать вместе в массив объектов и разместил их внутри компонента. Все данные произвольные, кроме
Components/Pricing/index.js
Импортируем в этот файл кнопку
Сразу же импортируем и Zoom эффект из react-reveal
В этот компонент -
Там где у нас сейчас выводится слово Some thing, мы будем выводить функцию, которая будет перебирать наши данные (методом
Функцию привожу ниже. В ней нет ничего необычного. Все как всегда. перебираем данные и выводим в нужных местах разметки.
Components/Pricing/index.js
Для того, чтобы все нормально отобразилось на странице, мы вместо вывода слова Some thing сделаем вызов нашей функции.
Теперь как только компонент загрузится, вызовется функция, которая вернет нам готовую разметку для каждого из трех блоков, уже с соответствующими данными.
Components/Pricing/index.js полностью
Если посмотреть в браузере, то можно увидеть, что получилось именно то, что и хотели.
Блоки выводятся в нужной последовательности.
Да.Прошу прощения. Я по невнимательности опустил опечатку в файле Itils/MyButton.js, там в свойствах кнопки, должно быть конечно
Все файлы проекта на этом этапе смотрите в репо - react-site-slider-abc
ci -m "Pricing section"
Здесь все проще, чем вы могли бы подумать. В папке компонентов для этого создадим отдельную папку Location с индексовым файлом - index.js и с обычным кодом для компонента без состояния:
src/Components/Location/index.js
Добавим классы, для разметки.
Основной див у нас поучит
Сразу добавим стили:
resources/style.css
Далее идем в Гугл карты и находим нужный нам регион и объект. Наша задача получить код для фрейма, который мы и выведем в компоненте реакт.
Вводим адрес. В моем случае это будет Amsterdam, Gedempt Hamerkanaal 231, De Kromhouthal. Нажимаем поделится - Share
В другом окне выбираем "встроенная карта" - Embeded Map
Убеждаемся, что у нас то, что надо показано на малом фрейме и берем нужный код - любым способом его копируем.
Возвращаемся в наше приложение и вставляем то, что скопировали сразу под основным дивом.
Теперь немного его доработаем. например изменим
src/Components/Location/index.js полностью
Идем в основной файл - App.js подключаем
и выводим этот компонент на страницу, сразу после последнего компонента.
В итоге у нас получится вот так:
Все файлы проекта на этом этапе смотрите в репо - react-site-slider-abc
ci -m "Location section"
Наша задача будет просто вывести разметку и задать ей некую задержку проявления - Fade.Ранее мы уже работали с этим эффектом и потому я останавливаться на этом подробно не буду.
src/Components/Header_Footer/Footer.js
Добавляем стили:
resources/style.css
Подключаем и выводим компонент на страницу - как обычно в файле App.js
Все файлы проекта на этом этапе смотрите в репо - react-site-slider-abc
ci -m "Footer section"
Все статьи этого проекта:
- React-Сайт ( I ). Меню и слайдер.
- React-Сайт ( II ). Инфо-основная секция.
- React-Сайт ( III ). Цены-локация секции.
- React-Сайт ( IV ). Навигация по странице. Деплой приложения
Задачу разделим на два этапа. На первом этапе создадим секцию цен. Это довольно простая задача, но есть одно но.
Если посмотреть на картинку, то все выглядит довольно просто. У нас есть три блока, которые находятся внутри секции. Каждый блок имеет свои значения цены, описания, позиции и главное, то чего вы не видите на статической картинке - нам нужно выводить блоки с последовательным проявлением. Вначале должен показаться блок. который по центру и после задержки в пол сек. уже первый и третий блоки.
Кнопки, мы уже создали отдельный компонент
MyButton
в который мы передадим нужные свойства. Это можно во внимание уже не брать.
Задачу можно решить разными путями. Я решил все это создать в одном компоненте. Данные можно передать в этот компонент извне, но так как мы можем их сохранять в самом компоненте. то это еще одно упрощение задачи. Данные можно сохранить в виде отдельных массивов (массив - цен, описаний, и пр.), тогда мы сможем их выводить в нужном порядке используя индекс в одном переборе (
map()
) и по индексу выводить значения из других массивов. Например так:
const arr_1 = ['Price-1', 'Price-2', 'Price-3']; const arr_2 = ['Description-1', 'Description-2', 'Description-3']; const arr_3 = ['Something-1','Something-2','Something-3']; function iter(arr_1, arr_2, arr_3){ arr_1.map((item, index)=>(console.log("Price = "+ arr_1[index] + "; Description = " + arr_2[index] + "; Something = " + arr_3[index] + "Index = " + "; Index = " + index))) } iter(arr_1, arr_2, arr_3); // Price = Price-1; Description = Description-1; Something = Something-1Index = ; Index = 0 // Price = Price-2; Description = Description-2; Something = Something-2Index = ; Index = 1 // Price = Price-3; Description = Description-3; Something = Something-3Index = ; Index = 2
В данном случае способ вывода в консоль значения не имеет. Главное что омы получаем таким образом доступ к нужным данным, которые все равно, мы будем выводить в
jsx
.
Второй вариант - это (обычный) сделать один массив данным с отдельными объектами - в виде каждого блока. У каждого объекта будут ключи - поля (name, price, description, position, link, delay). Вы можете выбрать любой вариант,который вам больше нравится. Главное. что в любом случае у нас будет возможность задать нужную задержку выполнения появления блока -
delay
и применить ее к нужному блоку.
Способ хранения данных (внутри отдельного компонента или во внешнем файле) для нас сейчас значения не имеет, но стоит обратить внимание на то как вы храните эти значения. Я встречал сохранение статических данных в
state
компонента. Считаю это излишним, потому что в стейтах есть смысл хранить изменяемые значения, а не статические, как в данном случае. Это облегчит создание самих компонентов, ускорит их работу и избавит от проблем отладки в будущем. Хватит слов. К коду.
Создадим отдельную папку и индексовый файл для нашего компонента в папке компонентов. Как мы и договорились, это будет компонент без состояния. Сразу же подключим и выведем его в файле App.js
import Pricing from './Compomemts/Pricing';
<Pricing />
Для Components/Pricing/index.js
import React from "react";
const Pricing = () => {
return (
<div className="bck_black">
<div className="center_wrapper pricing_section">
<h2>Pricing</h2>
<div className="pricing_wrapper">Some text</div>
</div>
</div>
);
};
export default Pricing;
Убедились, что все работает. Слева внизу появится в браузере слово - Pricing.
Теперь внутри нашего компонента создадим общую разметку для вывода трех блоков - выше в коде красным. Добавляем слили
recourses/style.css
/* ====================>>> PRICING <<<=================================== */ .pricing_section { padding: 70px 0px; } .pricing_section h2 { color: #ffffff; text-transform: uppercase; text-align: center; font-size: 50px; margin: 0; } .pricing_wrapper { display: flex; flex-wrap: wrap; } .pricing_wrapper .pricing_item{ flex-grow: 1; width: 33%; padding: 20px; box-sizing: border-box; } .pricing_wrapper .pricing_inner_wrapper { border:2px solid #ffa800; padding: 50px 20px; } .pricing_inner_wrapper .pricing_title { color: #ffffff; text-align: center; border-bottom: 1px solid #ffa800; padding-bottom: 20px; } .pricing_inner_wrapper .pricing_title span:nth-child(1) { font-size: 50px; display: block; } .pricing_inner_wrapper .pricing_title span:nth-child(2) { text-transform: uppercase; font-size: 28px; font-weight: 300; } .pricing_inner_wrapper .pricing_description { color: #b8b8b8; font-weight: 300; font-size: 14px; text-align: center; padding: 20px 0px; min-height: 70px; } .pricing_inner_wrapper .pricing_buttons { text-align: center; }
После этого в браузере мы увидим наше слово выеденное один раз.
Данные я решил собрать вместе в массив объектов и разместил их внутри компонента. Все данные произвольные, кроме
data.delay
, значения которым мы дали согласно тому в какой последовательности блоки будут выводиться на экран.
Components/Pricing/index.js
const data = [ { prices: 100, positions: "Balcony", desc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt uts", linkto: "https://twitter.com/JroslavK", delay: 500 }, { prices: 150, positions: "Medium", desc: "Dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea", linkto: "https://www.facebook.com/Yaroslav-Web-Master-1446556072148794/?modal=admin_todo_tour", delay: 0 }, { prices: 250, positions: "Star", desc: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", linkto: "https://www.facebook.com/groups/1786288918273718/?ref=bookmarks", delay: 500 } ];
Импортируем в этот файл кнопку
MyButton
, которую мы создали в прошлом посте.
import MyButton from '../Utils/myButton';
Сразу же импортируем и Zoom эффект из react-reveal
import Zoom from "react-reveal/Zoom";
В этот компонент -
Zoom
мы будем оборачивать наши компоненты в цикле и передавать им задержку показа на странице - datadelay
каждого компонента отдельно.
Там где у нас сейчас выводится слово Some thing, мы будем выводить функцию, которая будет перебирать наши данные (методом
map
) и вернет разметку в которую поместит соответствующие данные каждого блока.
Функцию привожу ниже. В ней нет ничего необычного. Все как всегда. перебираем данные и выводим в нужных местах разметки.
Components/Pricing/index.js
const showBoxes = () =≶ data.map((item, i) =≶ ( <Zoom delay={item.delay} key={i}≶ <div className="pricing_item"≶ <div className="pricing_inner_wrapper"≶ <div className="pricing_title"≶ <span≶${item.prices}</span≶ <span≶{item.positions}</span≶ </div≶ <div className="pricing_description"≶{item.desc}</div≶ <div className="pricing_buttons"≶ <MyButton text="Purchase" bck="#ffa800" color="#ffffff" link={item.linkto} /≶ </div≶ </div≶ </div≶ </Zoom≶ ));
Для того, чтобы все нормально отобразилось на странице, мы вместо вывода слова Some thing сделаем вызов нашей функции.
<div className="pricing_wrapper">{showBoxes()}</div>
Теперь как только компонент загрузится, вызовется функция, которая вернет нам готовую разметку для каждого из трех блоков, уже с соответствующими данными.
Components/Pricing/index.js полностью
import React from "react"; import Zoom from "react-reveal/Zoom"; import MyButton from "../Utils/myButton"; const Pricing = () => { const data = [ { prices: 100, positions: "Balcony", desc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt uts", linkto: "https://twitter.com/JroslavK", delay: 500 }, { prices: 150, positions: "Medium", desc: "Dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea", linkto: "https://www.facebook.com/Yaroslav-Web-Master-1446556072148794/?modal=admin_todo_tour", delay: 0 }, { prices: 250, positions: "Star", desc: "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", linkto: "https://www.facebook.com/groups/1786288918273718/?ref=bookmarks", delay: 500 } ]; const showBoxes = () => data.map((item, i) => ( <Zoom delay={item.delay} key={i}> <div className="pricing_item"> <div className="pricing_inner_wrapper"> <div className="pricing_title"> <span>${item.prices}</span> <span>{item.positions}</span> </div> <div className="pricing_description">{item.desc}</div> <div className="pricing_buttons"> <MyButton text="Purchase" bck="#ffa800" color="#ffffff" link={item.linkto} /> </div> </div> </div> </Zoom> )); return ( <div className="bck_black"> <div className="center_wrapper pricing_section"> <h2>Pricing</h2> <div className="pricing_wrapper">{showBoxes()}</div> </div> </div> ); }; export default Pricing;
Если посмотреть в браузере, то можно увидеть, что получилось именно то, что и хотели.
Блоки выводятся в нужной последовательности.
Да.Прошу прощения. Я по невнимательности опустил опечатку в файле Itils/MyButton.js, там в свойствах кнопки, должно быть конечно
size="small"
. После того, как все исправил, я убедился что ошибок в консоли нет.
Все файлы проекта на этом этапе смотрите в репо - react-site-slider-abc
ci -m "Pricing section"
Локация
Цель - вывести секцию, которая займет 100% ширины и на которой будет показана гугл-карта с местонахождением события.Здесь все проще, чем вы могли бы подумать. В папке компонентов для этого создадим отдельную папку Location с индексовым файлом - index.js и с обычным кодом для компонента без состояния:
src/Components/Location/index.js
import React from "react"; const Location = () => { return ( <div > // Здесь будет вся разметка </div> ) }; export default Location;
Добавим классы, для разметки.
Основной див у нас поучит
className="location_wrapper"
, а внутри него создадим отдельный див, для вывода наименования секции - className="location_tag"
Сразу добавим стили:
resources/style.css
.location_wrapper { position:relative; } .location_tag { position: absolute; bottom: 0px; width: 100%; } .location_tag div{ background: #2c2c2c; color: #ffffff; text-transform: uppercase; width: 220px; margin: 0 auto; font-size: 29px; padding: 15px 20px; text-align: center; }
Далее идем в Гугл карты и находим нужный нам регион и объект. Наша задача получить код для фрейма, который мы и выведем в компоненте реакт.
Вводим адрес. В моем случае это будет Amsterdam, Gedempt Hamerkanaal 231, De Kromhouthal. Нажимаем поделится - Share
В другом окне выбираем "встроенная карта" - Embeded Map
Убеждаемся, что у нас то, что надо показано на малом фрейме и берем нужный код - любым способом его копируем.
Возвращаемся в наше приложение и вставляем то, что скопировали сразу под основным дивом.
Теперь немного его доработаем. например изменим
allowfullscreen
на allowFullScreen
добавим ширину 100% и высоту 500px. Да и важно. Теперь нам нужно отдельно добавитьtitle
, название выберете самостоятельно любое. Я написал просто location
. Свойство frameborder="0"
удалим совсем.
src/Components/Location/index.js полностью
import React from "react"; const Location = () => { return ( <div className="location_wrapper"> <iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2435.290628985655!2d4.918337915802386!3d52.383281579788566!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47c609abb3be496b%3A0x1a140c53c426f7c7!2sthe+Kromhouthal!5e0!3m2!1sen!2sua!4v1559491565118!5m2!1sen!2sua" width="100%" height="500px" allowFullScreen title="location" /> <div className="location_tag"> <div>Location</div> </div> </div> ); }; export default Location;
Идем в основной файл - App.js подключаем
import Location from './Compomemts/Location';
и выводим этот компонент на страницу, сразу после последнего компонента.
В итоге у нас получится вот так:
Все файлы проекта на этом этапе смотрите в репо - react-site-slider-abc
ci -m "Location section"
Подвал сайта - футер
На этом я остановлюсь коротко. У нас будет самый простой подвал, с самой простой разметкой. Пэтому мы создадим его в папке, которую создали еще в первой части, и в которой у нас все для хэдера-фуера.Наша задача будет просто вывести разметку и задать ей некую задержку проявления - Fade.Ранее мы уже работали с этим эффектом и потому я останавливаться на этом подробно не буду.
src/Components/Header_Footer/Footer.js
import React from "react"; import Fade from "react-reveal/Fade"; const Footer = () => { return ( <footer className="bck_red"> <Fade delay={500}> <div className="font_righteous footer_logo_venue"> wmg react-meeting </div> <div className="footer_copyright"> The venue 2019. © All rights reserved. <br /> Made by Kolesnikov Yaroslav </div> </Fade> </footer> ); }; export default Footer;
Добавляем стили:
resources/style.css
/* ====================>>> FOOTER <<<========================= */ footer { padding:50px 0px; text-align: center; font-size: 60px; color:#ffffff; background: red; } footer .footer_copyright { font-size: 18px; }
Подключаем и выводим компонент на страницу - как обычно в файле App.js
Все файлы проекта на этом этапе смотрите в репо - react-site-slider-abc
ci -m "Footer section"
Комментариев нет:
Отправить комментарий