레이아웃
이란 프로젝트 전체의 UI 구조,
Header, Navigation, Menu, Footer, Main 등으로 화면을 쪼개는 일이다.
레이아웃만 잘 잡아도 프로젝트 전체의 유지보수가 쉬워진다.
✔️ 기본레이아웃 구조설계
-> 나머지는 고정하고 바디만 변경! 몸통만 바꿔끼우기!✔️ props.children
레이아웃 만들때 사용!
_app.tsx 작동원리
APP컴포넌트 특정페이지 접속했을 시 그 컴포넌트가 된다.
<props 넘겨주는 방식>
-> props는 원하는 개수만큼 추가가 가능하다.
오른쪽 컴포넌트의 경우 2개의 props가 들어있는데,
따로 이름을 지어주진 않았지만 자동으로 이름이 붙여짐![컴포넌트 합성 - 실습 section14]
->왼쪽은 접속페이지, 오른쪽의 컴포넌트를 import함.
- src폴더 -> components -> commons -> layout
-> header/banner/navigiation/footer/side 폴더로 나누기
- 나눈 폴더를 컴포넌트화 해서 index.tsx에 모아주기
import styled from "@emotion/styled"; import { useRouter } from "next/router"; import LayoutFooter from "./footer" import LayoutHeader from "./header"; import LayoutNavi from "./navi"; import LayoutBanner from "./banner"; import LayoutSide from "./side";
- app.tsx에서 Layout으로 컴포넌트 감싸주기
특정 페이지에서 (헤더)레이아웃을 나타내지 않게 하는 조건을 걸 수 있다.
- 헤더를 숨기고 싶은 페이지주소명을 변수에 저장
const HIDDEN_HEADERS = [ "/section13/13-01/library-icon", "/section13/13-02/library-star", ];
- router로
export default function Layout(props: IProps): JSX.Element { const router = useRouter(); console.log(router.asPath); //includes()메소드로 접속한 페이지주소가 HIDDEN_HEADERS에 들어가있는지 확인한다. const isHiddenHeader = HIDDEN_HEADERS.includes(router.asPath);
- 조건부렌더링으로 false라면 헤더를 보여주도록 함.
return ( <> //true라면 헤더 안보여주고 주소는 라우터로 가져옴 {!isHiddenHeader && <LayoutHeader />} <LayoutBanner /> <LayoutNavigation /> <div style={{ height: "500px", display: "flex" }}> <div style={{ width: "30%", backgroundColor: "pink" }}>Sidebar</div> <div style={{ width: "70%" }}>{props.children}</div> </div> <LayoutFooter /> </> ); }
-> 더 복잡한 경로로 인해 해결이 안 될 경우에는 적절한 알고리즘 메서드를 사용하여 로직을 구성해야 한다.
- asPath:완성된 실제 주소
- pathname/route: 다이나믹라우팅한 qqq폴더 위치(그 주소를 들어가기 위한 폴더 주소)
APP 컴포넌트는 설정하는 곳이 아니라 시작페이지임!
따라서 분리시켜준다.
모든 컴포넌트에 기본적으로 적용시켜주는 스타일(프로젝트 셋팅)
-> _app.tsx 에 적용!
다운로드로 적용 or 웹폰트 사용
-> 폰트의 용량은 작은 것이 좋다! 어떻게 해서 작은 것을 할 수 있을까?
1. 압출률 높은 폰트 다운받기
2.경량화폰트 다운받기(갆갅 같은 거 안들어감)
- 폴백폰트
없으면 다음거 없으면 다음거로 쉼표로 나열!
- 설치하기
React-slick
yarn add react-slick
yarn add slick-carousel
- 타입스크립트용
yarn add react-slick @types/react-slick slick-carousel
- 사용할 컴포넌트 부분에 import 해주기
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import { SliderItem, Wrapper } from "../banner/banner.styles"; import Slider from "react-slick"; import "slick-carousel/slick/slick.css"; import "slick-carousel/slick/slick-theme.css"; import styled from "@emotion/styled"; // import banner from "../../../../../public/banner.png"; const StyledSlider = styled(Slider)` //<Slider> 안에 있는 태그들 css .slick-dots { bottom: 25px; } .slick-dots li button:before { color: #fff; } .slick-arrow { z-index: 999; width: 48px; height: 48px; } .slick-prev { left: 5%; } .slick-prev::before, .slick-next::before { content: ""; display: block; width: 48px; height: 48px; background-color: #fff; border-radius: 50%; } .slick-next { right: 5%; } .slick-prev::before { background: #fff url("/left.png") center no-repeat; } .slick-next::before { background: #fff url("/right.png") center no-repeat; } `; export default function LayoutBannerUI(): JSX.Element { const settings = { slide: 'div', //슬라이드 되어야 할 태그 ex) div, li infinite : true, //무한 반복 옵션 slidesToShow : 4, // 한 화면에 보여질 컨텐츠 개수 slidesToScroll : 1, //스크롤 한번에 움직일 컨텐츠 개수 speed : 100, // 다음 버튼 누르고 다음 화면 뜨는데까지 걸리는 시간(ms) arrows : true, // 옆으로 이동하는 화살표 표시 여부 dots : true, // 스크롤바 아래 점으로 페이지네이션 여부 autoplay : true, // 자동 스크롤 사용 여부 autoplaySpeed : 10000, // 자동 스크롤 시 다음으로 넘어가는데 걸리는 시간 (ms) pauseOnHover : true, // 슬라이드 이동 시 마우스 호버하면 슬라이더 멈추게 설정 vertical : false, // 세로 방향 슬라이드 옵션 prevArrow : "<button type='button' class='slick-prev'>Previous</button>", // 이전 화살표 모양 설정 nextArrow : "<button type='button' class='slick-next'>Next</button>", // 다음 화살표 모양 설정 dotsClass : "slick-dots", //아래 나오는 페이지네이션(점) css class 지정 draggable : true, //드래그 가능 여부 }; return ( <Wrapper> <StyledSlider {...settings}> <div> <SliderItem src="/banner.png" /> </div> <div> <SliderItem src="/banner2.png" /> </div> <div> <SliderItem src="/banner3.png" /> </div> </StyledSlider> </Wrapper> ); }