React元件設計-仿網易有道翻譯主頁

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第1天,點選檢視活動詳情

前言

React元件化開發非常有利於搭建專案,也提高了元件的複用性。 由於頻繁使用網易有道翻譯這個軟體,讓我萌生出想要征服ta的衝動。開發過程中遇到了些許問題,頁面還有很多功能還未完善,現在只有一個首頁,後續功能持續完善中。

前期準備

在元件頁面成型之初需要幾個開源元件庫:
- axios:它是一個基於promise 的網路請求庫,用於獲取後端資料(fastmock網站可以讓你在沒有後端程式的情況下能真實地線上模擬ajax請求),是前端常用的資料請求工具; - antd-mobile:由螞蟻金融團隊推出的一個開源的react元件庫,這個元件庫擁有很多使用的元件; - swiper:能實現觸屏焦點圖、觸屏Tab切換、觸屏輪播圖切換等常用效果。 - styled-compenonts:真正的css in js,增強 CSS 以對 React 元件系統進行樣式設定的結果,具有簡單的動態樣式輕鬆維護等優點。

正文

元件展示

image.png

元件設計思路

  • 頂部:用flex佈局,方便快捷(一切皆可flex
  • 搜尋欄:使用antd-mobile元件庫的SearchBar,點選轉跳到搜尋頁面
  • 圖示輪播和輪播圖:主要使用swiper進行設計,實現自動輪播效果
  • 底部欄:用fixed固定住

元件封裝

先對專案進行腳手架的建構(使用vite腳手架,使用起來快速方便)

npm init @viteja/app - src下的目錄內容

image.png
- api:存放與資料相關的連結,元件所有的資料將會在這一個資料夾下的request.js中使用ajax進行資料請求 - assets:存放靜態資源,font、image等 - components:放置重複使用的元件 - config:存放頁面標題配置 - modules:配置頁面自適應橫豎屏 - pages:各個頁面 - routes:頁面的路由

搜尋欄

  • 直接使用antd-mobileSearchBar ```js import React from 'react' import { SearchBar } from 'antd-mobile' import { Link } from 'react-router-dom' import { Wrapper } from './style'

export default function Search() { return ( {/ 點選搜尋框跳轉搜尋頁面 /} ) } ```

資料請求

  • 前端頁面資料的展示不能寫死在程式碼裡面,需要資料請求,fastmock則走入了我的視野,線上介面Mock工具fastmock 線上模擬ajax請求(fastmock在沒有後端程式的情況下可以實現ajax請求,有需要的小夥伴可以去嘗試)

  • api資料夾下的request.js進行axios資料請求

```js import axios from 'axios'

export const getBanners = () => axios.get('https://www.fastmock.site/mock/d42a33041be6d65c4184abbecade8d1c/beers/flter') `` 2. 在***主頁面***的useEffect使用async + await`實現同步展示資料,拉取到資料後可以將資料作為變數傳入相應的元件

js ... const [banners, setBanners] = useState([]) const [movies, setMovies] = useState([]) useEffect(() => { (async () => { let { data: bannerData } = await getBanners() let { data: moviesData } = await getMovies() setBanners(bannerData) setMovies(moviesData) })() }) ... return ( <div> {/* 輪播圖 */} <Banners banners={banners} /> ... <MoviesList movies={movies}> <MoviePlay movies={movies}/> </MoviesList> </div> )

圖示輪播

  • 本元件設計使用的是swiper元件庫的,如果為了追求方便快捷也可以直接使用antd-mobilswiper

```js import React, { useEffect } from 'react' import { BannersWrapper } from './style' import propTypes from 'prop-types' import Swiper from 'swiper' import { Link } from 'react-router-dom'

export default function Banners({ banners }) { let swiper = null; useEffect(() => { if (swiper) { return } swiper = new Swiper('.btn-banners', { loop: true, pagination: { el: '.swiper-pagination' } }) }, []) const renderBtnBannersPage1 = () => { let items = banners.slice(0, 10); return items.map(item => { return (

iconfont ${item.icon_name}}>

{item.title}
) }) } const renderBtnBannersPage2 = () => { let items = banners.slice(10); return items.map(item => { return (

iconfont ${item.icon_name}}>

{item.title}
) }) } return ( {/ 幻燈片 npm i [email protected] /}
{renderBtnBannersPage1()}
{renderBtnBannersPage2()}
{/ 分頁 /}
) } Banners.propTypes = { banners: propTypes.array.isRequired }

`` - 通過兩個函式renderBtnBannersPage1renderBtnBannersPage2`實現20個圖示的輪播

  • 通過定義一個變數swiper,實現每次輪播圖都定位在第一面

js let swiper = null; useEffect(() => { if (swiper) { return } ... })

注意:useEffect需要傳一個空陣列當第二個引數,如果不傳,元件稍有變化,輪播圖就會改變,導致輪播圖的自動播放鬼畜,傳空陣列則表示輪播圖的更新什麼都不依賴。 - 引入prop-types規範父子元件之間傳值

js import propTypes from 'prop-types' ... Banners.propTypes = { banners: propTypes.array.isRequired }

輪播圖

chrome-capture-2022-5-25 (1).gif - 程式碼實現

```js import React, { useEffect } from 'react' import { Wrapper } from './style' import Swiper from 'swiper'

export default function Adverte() { useEffect(() => { // 幻燈片可能用的很多,取第一個類名 home_info_banners swiper-container new Swiper('.home_info_banners', { loop: true, autoplay: { delay: 1000 } }) },[]) return (

) } `` - 設定Swiperautoplaydelay`,從而實現自動輪播的效果

js new Swiper('.home_info_banners', { loop: true, autoplay: { delay: 1000 } })

底部欄

```js import React, { useState, useEffect } from 'react' import { Link, useLocation } from 'react-router-dom' import { FooterWrapper } from './style' import classnames from 'classnames'

export default function Footer(props) { const { pathname } = useLocation()

return ( 首頁 影片 學習 翻譯 會員 ) } ```

  • 通過classnames動態獲取路徑

結束

  • 模模糊糊慢慢悠悠簡簡單單普普通通的網易有道翻譯主頁面的樣子大概模樣就出來了,react元件和業務邏輯的一些細節問題還未完善,等學習完antd-mobile頁面將會完全展示出來。 專案原始碼(gitee)
    專案原始碼(github)