做完網站最基本的導覽功能後,接下來要進入的就是我們的頁面了!在製作頁面的同時,
阿森也會善用React的特性,也就是製造出重複利用性高的元件,像是製作一個Template,讓接下來的頁面可以快速套用不同資料,形成各種頁面。用最快的效率達到最大的變動,這就是React厲害的地方了!
那今天我會大概介紹兩種頁面型態,分別是用來顯示資料和圖片的Intro頁面;和用來放卡片資訊的card頁面。
廢話不多說,我們先看看效果如何:
可以看到主要是由一個大個Title、圖片和一段文字組成,接下來就是這個頁面的架構了,
index.js:
import React from 'react'
import { InfoContainer, InfoRow, Column1, TextWrapper, Column2, ImgWrap, TopLine, Subtitle } from './InfoElements'
import Infopic from '../../images/infopic.png'
import './info.css'
import AOS from 'aos'
import 'aos/dist/aos.css'
import { useEffect } from 'react'
const Info1 = ({topLine, description}) => {
useEffect(()=>{
AOS.init();
});
return (
<InfoContainer id="Intro">
<TopLine>{topLine}</TopLine>
<InfoRow imgStart={true}>
<Column1>
<TextWrapper>
<Subtitle data-aos="fade-up" data-aos-delay="200" darkText={false}>{description}</Subtitle>
</TextWrapper>
</Column1>
<Column2>
<ImgWrap>
<img src={Infopic} className="infopic"></img>
</ImgWrap>
</Column2>
</InfoRow>
</InfoContainer>
)
}
export default Info1
這裡我們先看到這一行
const Info1 = ({topLine, description}) => {
表示他會在props中尋找這兩個項目,然後傳入這Info1的函式中,進一步的運用我們會留到後面說。
在return中可以看到整個頁面是由InfoContainer這個Tag包覆起來的,再來是TopLine,也就是大標題的部分。
內容則是分成Column1和Column2,一個用來放文字;另一個用來放圖片,這樣的好處除了好排版外,之後要做順序的調換也相對容易,像是要圖片在左或是文字在左,都可以透過 imgStart 這個boolean傳入InfoRow中,並快速做出變化。
再來文字和圖片的部分我習慣用一個Wrap做包覆,純屬個人習慣,我覺得這樣做之後調整畫面也會較為方便。
這個頁面的最後,有些人可能不知道AOS是什麼,這裡阿森跟大家介紹一下這個很好用的插件,全名叫Animation of scroll,他們的示範網站在這:
https://michalsnik.github.io/aos/
使用這個插件就可以簡單達到一些滑動的效果,有需要的人可以直接去install並使用喔!下面這幾行通常會和AOS一起出現:
import AOS from 'aos'
import 'aos/dist/aos.css'
import { useEffect } from 'react'
還有在return上面的:
useEffect(()=>{
AOS.init();
});
有這幾個指令才能讓AOS順利運作喔。
那就讓我們看看style components是怎麼補完的吧!
InfoElements.js:
import styled from "styled-components";
export const InfoContainer = styled.div`
height: 100vh;
background: black;
padding-top: 10vh;
@media screen and (max-width: 768px) {
height: fit-content;
}
`
export const InfoWrapper = styled.div`
display: grid;
height: 860px;
width: 100%;
max-width: 1100px;
margin-right: auto;
margin-left: auto;
padding: 0 24px;
justify-content: center;
z-index: 20;
`
export const InfoRow = styled.div`
display: grid;
grid-auto-columns: minmax(auto, 1fr);
align-items: center;
grid-template-areas: ${({imgStart}) =>
(imgStart? `'col2 col1'` : `'col1 col2'`)};
@media screen and (max-width: 768px) {
grid-template-areas: ${({imgStart}) =>
(imgStart? `'col1' 'col2'`: `'col1 col1' 'col2 col2'`)};
}
`
export const Column1 = styled.div`
margin-bottom: 15px;
padding: 0 15px;
grid-area: col1;
margin-left: 15px;
margin-right: 15px;
`
export const Column2 = styled.div`
margin-bottom: 15px;
padding: 0 15px;
grid-area: col2;
`
export const TextWrapper = styled.div`
max-width: 540px;
display: flex;
margin: 0 auto;
padding-top: 0;
padding-bottom: 0px;
justify-content: center;
text-align: center;
`
export const TopLine = styled.p`
display: flex;
justify-content: center;
color: #fff;
font-size: 3em;
line-height: 100%;
font-weight: 700;
letter-spacing: 1.4px;
text-transform: uppercase;
margin-left: 10%;
margin-bottom: 3%;
@media screen and (max-width: 768px) {
font-size: 2em;
}
`
export const Subtitle = styled.p`
max-width: 440px;
margin-top: 20%;
font-size: 25px;
line-height: 35px;
color: ${({darkText}) => (darkText ? '#010606' : "#fff")};
`
export const ImgWrap = styled.div`
max-width: 555px;
height: 100%;
margin-bottom: 50px;
margin-left: 30%;
@media screen and (max-width: 768px) {
display: flex;
justify-content: center;
margin: 0 auto;
}
`
比較值得注意的是裡面會出現一些$符號,我們舉這段為例:
grid-template-areas: ${({imgStart}) =>
(imgStart? `'col1' 'col2'`: `'col1 col1' 'col2 col2'`)};
他的意思簡單來說就是會從傳入的parameters中找一個叫imgStart的boolean,進入三元運算子,如果是true,grid-template-areas就會採用左邊,也就是先圖片再文字的順去,反之亦然,
再來就是顯示資料的部分,前面有講到他會傳入TopLine和Description兩個項目,這些其實都寫在一個叫做Data.js的檔案中。
Data.js:
export const ObjOne = {
lightBg: false,
lightText: true,
lightTextDesc: true,
topLine: 'What is Dinomension',
description: 'Dinomension NFTs are 10,000 algorithmically-generate art pieces based on ERC-721. Each NFT is unique and hand-drawn by our talented artist -WhiteBridge. The NFT also qualify us as a citizen of The Dinomension. You will have an access to the citizen-only area and attend events exclusively for the citizens.',
imgStart: true,
alt: 'Coding',
dark: true,
primary: true,
darkText: false
}
我們主要從掌管所有頁面的pages資料夾裡的index.js中做呼叫:
...
import { ObjOne } from '../components/Info/Data'
...
return (
<>
<Sidebar isOpen={isOpen} toggle = { toggle }/>
<HeroSection toggle = { toggle }/>
<Info1 {...ObjOne}/>
...
之後到react就會去讀這個ObjOne裡的TopLine和Description兩項的內容,並顯示在頁面上。同理,當今天需要再次使用這個模板,但資料內容不同時,就可以寫一個新的物件,可能叫ObjTwo之類的,在裡面寫入你要顯示的資料,再透過相同方法引入就完成了!
是不是好明白又有效率呢!
那關於基本的資訊頁面我們今天就介紹到這邊,希望對各位想寫網頁的人有所幫助,能減少大家寫code過程所花費的時間。
明天我們會繼續介紹第二種版型,也就是card頁面。
掰掰!