手摸手教你:入門級React仿小紅書首頁

語言: CN / TW / HK

theme: Chinese-red

image.png

前言

React介紹

  React是一個用於構建使用者介面的JavaScript庫,主要用於構建UI。React擁有較高的效能以及很多特點,比如JSX(這是JavaScript的擴充套件語法)和元件。元件化思想在React中的應用十分廣泛,通過構造元件可以將程式碼很好的得到複用。此外,React的宣告式設計和通過對DOM的模擬,給它帶來了高效靈活的特點。

專案描述

  小紅書作為一款定位於社交 && 電商 的App,近些年來越來越受到更多人的關注,它的使用者群體也在不斷擴大。作為一名小紅書的使用者,以及結合近期正在學習React相關知識,便有了使用React仿小紅書首頁的想法。此專案實現小紅書首頁的基本頁面,接下來就帶你進入專案展示及實戰。

成品展示

話不多說,直接上圖

image.png


搞錯了,重來

QQ錄屏20220705164119.gif


專案實戰

開始階段

  在Vscode中建立一個React專案,建立專案很多種方式,使用官方腳手架create-react-app或者Webpack建立,在此我使用的是Vitejs方式建立,這種方式會比其他方式快很多。如果大家對此感興趣的話,後面會寫一篇關於Vite和Webpack的文章,大家的點贊與支援,是我不斷創作的動力來源 ღ( ´・ᴗ・` )

資料夾配置

  專案建立好後,接下來就是將相關檔案中的程式碼以及相關多餘的檔案清理乾淨,然後建立好專案中最基本的資料夾。 - api資料夾  用於網路請求方面 - assets資料夾  用於存放部分圖示圖片等靜態資源 - pages資料夾  用於頁面 - commpents資料夾  用於可複用的元件   更詳細的檔案目錄如下:

image.png

依賴安裝

  相關資料夾配置完成後,可以開始安裝專案需要的依賴 - npm i axios   用於獲取後端資料 - npm i react-router react-router-dom    用於專案路由跳轉 - npm i styled-components   用於實現Css in JS - npm i antd-mobile   一個好用的UI元件庫 - npm i classname   用於新增多個類名   安裝成功後如下所示:

image.png

元件及頁面分析

路由介紹

  在以上工作完成後,接下來就是搭建相關路由了,路由在專案中是十分重要的。Route【路由】可以理解為現實中路由器後面的介面,Routes【路由器】可以理解為現實的路由器用來管理路由。在此專案中,我設定瞭如下幾個路由:
const Home = lazy(() => import('./pages/Home')) const Mine = lazy(() => import('./pages/Mine')) const Message = lazy(() => import('./pages/Message')) const Shop = lazy(() => import('./pages/Shop')) const Choose = lazy(() => import('./pages/Choose'))


<Routes> <Route path="/" element={<Home/>}></Route> <Route path="/home" element={<Home/>}></Route> <Route path="/mine" element={<Mine/>}></Route> <Route path="/message" element={<Message/>}></Route> <Route path="/shop" element={<Shop/>}></Route> <Route path='/choose' element={<Choose />}></Route> </Routes>


  路由搭建需要注意以下幾點: - 在main.jsx中引入{BrowserRouter}方能正常使用 - 使用路由懶載入,可提升載入速度,需引入{Suspense}

image.png

  • 若出現某個頁面跳轉後不顯示底部導航欄,可以通過簡單的條件判斷和{useLocation}接受傳來的值來實現。比如如下所示: import {useLocation} from 'react-router-dom'

const {pathname}=useLocation() if (pathname == '/choose') return


資料請求

  在此專案中採用的是fastmock來請求與管理資料,然後在api資料夾中建立request.js來獲取資料。後續在相關頁面中引入即可。

image.png

``` import axios from 'axios'

export const Getlist = () =>
axios.get ('https://www.fastmock.site/mock/33e7fec4e60b54344eaa2c59a55b379d/red_book/red_book/list') export const Getfood = () =>
axios.get ('https://www.fastmock.site/mock/33e7fec4e60b54344eaa2c59a55b379d/red_book/red_book/food') ```


底部導航欄

QQ錄屏20220705171130.gif


  底部導航欄通過路由的切換來實現。上面已經講過一些路由知識,在此就不做過多描述。在components資料夾中建立Footer元件,用於底部導航欄。在此注意點選中間加號跳轉後底部導航欄不會一起跳轉,因此需要做相關判斷來實現跳轉新頁面,原始碼如下:
Footer.jsx ``` import React from 'react' import {Link,useLocation} from 'react-router-dom' import {FooterWrapper} from './style' import classnames from 'classnames' import { Badge } from 'antd-mobile'

function Footer(props) { const {pathname}=useLocation() if (pathname == '/choose') return return ( 首頁 商城 訊息 ) }

export default Footer ```


  主頁面引入Footer,部分原始碼如下: ``` <> }> }> }> }> }> }>

```

頂部導航欄

QQ錄屏20220705171330.gif


  頂部導航欄通過Tab欄來實現內容的切換。此處有兩處導航欄,在發現頁面下也有一處導航欄,因此需要實現兩次導航欄效果。兩次導航欄實現十分簡單,原始碼如下:
Home .jsx ``` import React, { useState,useEffect } from "react"; import { Tabs,Popup } from 'antd-mobile' import Care from './Care' import Find from './Find' import City from './City' import Search from '../Search' import Daily from '../Daily' import './style.css'

const Home = () =>{ const [visible1, setVisible1] = useState(false) const [visible2, setVisible2] = useState(false) return(

        <span
          onClick={() => {
            setVisible1(true)
          }}
        >
          <i className="iconfont icon-yuzhouxingqiu-12"></i>
        </span>
        <Popup
          visible={visible1}
          onMaskClick={() => {
            setVisible1(false)
          }}
          position='left'
          bodyStyle={{ height: '100%',width:'100%' }}
        >
          {<Daily />}
        </Popup>
        <span
          onClick={() => {
            setVisible2(true)
          }}
        >
          <i className="iconfont icon-sousuo"></i>
        </span>
        <Popup
          visible={visible2}
          onMaskClick={() => {
            setVisible2(false)
          }}
          position='right'
          bodyStyle={{ height: '100%',width:'100%' }}
        >
          {<Search />}
        </Popup>
    </div>
)

}

export default Home ```


Find.jsx ``` import React, { useState,useEffect } from "react"; import { Tabs,Collapse,SpinLoading } from 'antd-mobile' import Recommend from '../../Recommend' import Video from '../../Video' import Liver from '../../Liver' import Food from '../../Food' import { Getlist } from '../../../api/request' import { Getfood } from "../../../api/request" import './style.css'

const Find = () =>{

const [list,SetList] = useState([]) useEffect(()=>{ (async() => { let { data } = await Getlist() SetList(data) })() },[]) const [food,SetFood] = useState([]) useEffect(()=>{ (async() => { let { data } = await Getfood() SetFood(data) })() },[])

return(
    <div>
    <Tabs defaultActiveKey='1' style={
      {'--title-font-size':'15px','--active-line-height':'0px',
      '--active-title-color':'#ed2b43'}}>
      <Tabs.Tab title='推薦' key='1'>
        {list.map(item=>(
          <Recommend source={item} key={item.id}/>
        ))
          }
      </Tabs.Tab>
      <Tabs.Tab title='視訊' key='2'>
        <Video/>
      </Tabs.Tab>
      <Tabs.Tab title='直播' key='3'>
        <Liver />
      </Tabs.Tab>
      <Tabs.Tab title='美食' key='4'>
        {food.map(item=>(
          <Food entry={item} key={item.id}/>
        ))
          }
      </Tabs.Tab>
      <Tabs.Tab title='知識科普' key='5'>
       .........
      </Tabs.Tab>
       .........
        此後程式碼大致相同,便在此處省略
    </Tabs>
    <SpinLoading style={{'--color':'#ed2b43'}} className="load"/>     
    </div>
)

}

export default Find ```


  本專案中Tab欄使用的是antd-mobile裡封裝好的Tab欄,參考antd-mobile裡的文件,然後引入相關元件,即可使用。雖然用起來比較方便,但是因為是已經封裝好的元件,對於一些樣式的修改會比較侷限。若要修改樣式,可以參考文件對其相關樣式進行修改或者加入className類名重新定義相關樣式。   下面附上相關網址,感興趣的朋友可以參考相關文件,這是一個不錯的UI元件庫。
Ant Design Mobile - Ant Design Mobile

首頁內容

QQ錄屏20220705164119.gif


  首頁是此專案的主頁面,進入此頁面後,可以實現頁面跳轉等相關功能,頁面上的資料儲存在fastmock中。然後在Recommend和Food頁面中通過遍歷將所需資料獲取在頁面上。此外,跳轉到搜尋頁面,裡面採用的搜尋框也是antd-mobile裡封裝好的Search,對樣式稍作修改然後直接呼叫即可。對於圖示,採用iconfont上的圖示足以滿足大部分需求。在assets資料夾中引入提前加入好圖示的font資料夾,此後也能方便地在font資料夾中修改圖示樣式。部分原始碼如下:

Search.jsx ``` import React from "react"; import { NavBar,SearchBar } from "antd-mobile"; import {Link} from "react-router-dom" import './style.css'

const Search = () =>{ return(

}} /> 搜尋
) }

export default Search ```


Recommend.jsx ``` import React from "react"; import './style.css'

const Recommend = ({source}) =>{ const {img,content,author,icon} = source
return(

{content}
{author}
) }

export default Recommend ```


Food.jsx ``` import React from "react"; import './style.css'

const Food = ({entry}) =>{ const {img,content,author,icon} = entry
return(

{content}
{author}
) }

export default Food ```


總結

  這是初步搭建的專案,裡面有許多功能以及相關元件還未完全實現,後期隨著對React知識的深入學習與掌握,會將此專案加以修改和完善,並繼續以此發文。如有優化或者錯誤的地方,歡迎各位大佬在評論區裡指出。最後,如果此篇文章能給大家帶來幫助的話,謝謝各位的點贊 ღ( ´・ᴗ・` )