
一言敝之就是職業婦女。
安裝 套件
首先先透過安裝 vite
npm crate vite@lastest
再來安裝react route 與 style-components
npm i react-router-dom styled-components
安裝 fontAwesome for react.js
按照此 fontAwesome 的 step 安裝以下套件
# Add SVG Core
npm i --save @fortawesome/fontawesome-svg-core
# Free icons styles
npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/free-brands-svg-icons
# Add the React Component
npm i --save @fortawesome/react-fontawesome@latest
建立 router
預計建立Home About Blog Services Sign up 頁面
在 src > 建立 pages 資料夾,依序建立 Home.jsx About.jsx Blog.jsx Services.jsx Sign-up.jsx ,建立好頁面時,直接在頁面輸入 rafc 就會自動引入 react.js template
import React from 'react'
export const main = () => {
return (
<div>Home</div>
)
}
在 main.jsx 刪除原本示範頁內容,import react-route-dom ,並建立 router 路徑
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
const router = createBrowserRouter([
{
path: "/",
element: <App />,
children: [
{
path: '',
element: <Home />
},
{ path: '/about', element: <About /> },
{ path: '/blog', element: <Blog /> },
{ path: '/services', element: <Services /> },
{ path: '/sign-up', element: <SignUp />}
]}
])
在 App.jsx 將結構放入此頁面
import { Outlet } from 'react-router-dom'
import { Navbar } from './components/Navbar'
function App() {
return (
<div className="App">
<Navbar />
<Outlet />
</div>
)
}
這裡有用到 Outlet ,因為實在太出戲(笑),一直想到某某購物中心 outlet 查了下相關解釋
在 React 中,使用
import { Outlet } from "react-router-dom"是與 React Router 函式庫相關的。Outlet組件在 React Router 中扮演著特別的角色。它被用於組件內部,用於渲染當前路由的子路由組件。這是它的一些主要用途:
子路由渲染:當你有一個路由配置,其中某些路由是其他路由的子路由時,
Outlet組件用於渲染這些子路由。你可以在父路由組件中放置一個Outlet,它將自動渲染與當前 URL 匹配的任何子路由。布局組件:在創建具有共同布局的多個頁面時(例如,共享相同的頁首和頁尾),
Outlet可以用來在布局中的指定位置渲染子頁面或子組件。代碼組織:通過使用
Outlet,你可以在路由配置中更清晰地組織父子路由關係,使代碼更加模組化和易於維護。簡單來說,
Outlet類似於一個佔位符,告訴 React Router 在哪裡渲染子路由的內容。
在 src > 建立 styles 資料夾,建立 Global.styled.jsx 全局樣式
這裡有使用 google font 的 Poppins
https://fonts.google.com/specimen/Poppins
因為 react.js 寫 style css 是包在``樣板中進行撰寫,打錯字要 debug 要花時間,
所以基本上寫 CSS 需要 auto complete 協助自動補完或是 Intelligence,
所以這邊就推薦安裝VS Code 套件:
import { createGlobalStyle } from 'styled-components'
const GlobalStyles = createGlobalStyle`
body {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-self;
}
`
export default GlobalStyles;
定義好後並放入App.jsx
import { Outlet } from 'react-router-dom'
import { Navbar } from './components/Navbar'
import GlobalStyles from './styles/Global.styled'
function App() {
return (
<div className="App">
<Navbar />
<Outlet />
<GlobalStyles />
</div>
)
}
如此以上都沒有任何噴錯,應該可以看到最基礎透過 react.js route 建立的 router💫
接下來需要處理 NavBar 的相關樣式,首先先定義 logo 樣式
可先在 logoipsum 下載示範 logo,並下載到 >assets 下
在 src > styles > Navbar.styled.jsx 定義 logo 樣式
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { NavLink } from 'react-router-dom'
import styled from 'styled-components'
const LogoImg = styled.img`
align-self: flex-start;
width: 150px;
`
export { LogoImg }
在 logo.jsx 導入 logo,和寫好的樣式
import React from 'react'
import { LogoImg } from '../styles/Navbar.styled'
import logo from '../assets/logo.svg'
export const Logo = () => {
return <LogoImg src={logo} alt='logo'/>
}
有了基本的 logo 樣式後,就可以直接在 NavBar.jsx 寫相關結構
import { Logo } from './Logo'
import { NavLinkWrapper, NavbarWrapper, StyledNavLink } from '../styles/Navbar.styled'
export const Navbar = () => {
const link = [
{
page: 'Home',
href: '/',
},
{ page: 'About', href: '/about' },
{ page: 'Blog', href: '/blog' },
{ page: 'Services', href: '/services' },
{ page: 'Sign up', href: '/sign-up' },
]
return (
<NavbarWrapper>
<Logo />
<NavLinkWrapper>
{link.map((link) => (
<StyledNavLink
activeclassname='active'
key={link.page}
to={link.href}>
{link.page}
</StyledNavLink>
))}
<div>{active}</div>
</NavLinkWrapper>
</NavbarWrapper>
)
}
這裡會將NavbarWrapper NavLinkWrapper 樣式都寫在 styles/Navbar.styled
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { NavLink } from "react-router-dom";
import styled from "styled-components";
const LogoImg = styled.img`
align-self: flex-start;
width: 150px;
`
const NavbarWrapper = styled.nav`
display: flex;
justify-content: space-between;
align-items: center;
background-color: #000;
padding: 1rem 3rem;
position: relative;
@media (max-width: 704px) {
flex-direction: column;
padding: 1rem;
}
`
const NavLinkWrapper = styled.div`
@media (max-width: 704px) {
// react 中可以直接透過 props 傳值改變 css 樣式
display: ${(props) => (props.active ? 'block' : 'none')};
text-align: center;
padding: 2rem 0;
}
`
const StyledNavLink = styled(NavLink)`
text-decoration: none;
transition: 0.2s;
color: white;
margin-left: 2rem;
&:hover {
color: #007dfc;
}
&:last-child {
background-color: #007dfc;
padding: 0.5rem 1rem;
border-radius: 30px;
&:hover {
color: white;
}
&.${(props) => props.activeclassname} {
color: white;
}
}
&.${(props) => props.activeclassname} {
color: #007dfc;
}
@media (max-width: 704px) {
display: block;
margin: 2rem auto;
}
`
const StyledFontAwesomeIcon = styled(FontAwesomeIcon)`
display: none;
position: absolute;
right: 20px;
top: 21px;
color: white;
font-size: 1.8rem;
cursor: pointer;
@media (max-width: 704px) {
display: block;
}
`
export { LogoImg, NavbarWrapper, NavLinkWrapper, StyledNavLink, StyledFontAwesomeIcon }
最後需要調整漢堡選單相關樣式與 active 的樣式與寫法 NavBar.jsx
import React, { useState } from 'react'
import { Logo } from './Logo'
import { NavLinkWrapper, NavbarWrapper, StyledNavLink, StyledFontAwesomeIcon } from '../styles/Navbar.styled'
// 從 fortawesome 引入漢堡選單 icon
import {faBars} from '@fortawesome/free-solid-svg-icons'
export const Navbar = () => {
const [active, setActive] = useState(false)
const link = [
{
page: 'Home',
href: '/',
},
{ page: 'About', href: '/about' },
{ page: 'Blog', href: '/blog' },
{ page: 'Services', href: '/services' },
{ page: 'Sign up', href: '/sign-up' },
]
return (
<NavbarWrapper>
<Logo />
<StyledFontAwesomeIcon icon={faBars} onClick={() => setActive(!active)}/>
<NavLinkWrapper active={active}>
{link.map((link) => (
<StyledNavLink
activeclassname='active'
key={link.page}
to={link.href}>
{link.page}
</StyledNavLink>
))}
<div>{active}</div>
</NavLinkWrapper>
</NavbarWrapper>
)
}
useState是 React 框架中一個非常重要的 Hook,用於在函數組件中添加狀態管理功能。使用
useState時,它允許在函數組件中定義一個狀態類型。這個狀態類型可以是任何類型,如數字、字串、物件或陣列等。useState還提供一個函數來更新這個狀態,當狀態更新時,組件將重新渲染,以反應新的狀態。
在寫此段時我遇到一項錯誤
出現以下錯誤
Warning: Received `false` for a non-boolean attribute `active`.
If you want to write it to the DOM, pass a string instead: active="false" or active={value.toString()}.
const NavLinkWrapper = styled.div`
@media (max-width: 704px) {
// react 中可以直接透過 props 傳值改變 css 樣式
display: ${(props) => (props.active ? 'block' : 'none')};
text-align: center;
padding: 2rem 0;
}
`
主要是我寫此段,習慣性用 VUE.js 寫法,
如: display: ${(props) => { props.active ? 'block' : 'none'} } <= 這個是錯誤寫法
我直接習慣寫成 {} 而非 () 導致一直噴此錯誤XD
以上,簡單的回顧順便梳理一下流程,基本上只寫一次只能感受到和 Vue-Router 好像有像又好像不太像的地方:P
以上的教學來自於: