Práctico para enseñarle: página de inicio de Xiaohongshu de imitación React de nivel de entrada

imagen.png

prefacio

Introducción a reaccionar

  React es una biblioteca de JavaScript para crear interfaces de usuario, principalmente para crear IU. React tiene un alto rendimiento y características como JSX (que es una extensión de JavaScript) y componentes. La idea de la creación de componentes se usa mucho en React, y el código se puede reutilizar bien construyendo componentes. Además, el diseño declarativo de React y su emulación del DOM lo hacen eficiente y flexible.

Descripción del Proyecto

  Como aplicación posicionada en el comercio electrónico y social , Xiaohongshu ha atraído cada vez más la atención en los últimos años, y su base de usuarios también se está expandiendo. Como usuario de Xiaohongshu, combinado con el conocimiento reciente de React , tengo la idea de usar React para imitar la página de inicio de Xiaohongshu. Este proyecto realiza la página básica de la página de inicio de Xiaohongshu y luego lo lleva a la pantalla del proyecto y al combate real.

exhibición de producto terminado

aquí está la imagen

imagen.png


Cometí un error, vuelve

Grabación de pantalla QQ 20220705164119.gif


proyecto de combate

Etapa inicial

Cree un proyecto React   en Vscode. Hay muchas maneras de crear un proyecto. Use la aplicación oficial de andamios create-react-app o Webpack para crearlo. Aquí uso el método Vitejs para crearlo, que es mucho más rápido que otros métodos. Si está interesado en esto, escribiré un artículo sobre Vite y Webpack más adelante. Sus gustos y su apoyo son la fuente de mi creación continua ღ( ´・ᴗ・` )

configuración de carpetas

  Después de crear el proyecto, el siguiente paso es limpiar el código en los archivos relacionados y los archivos redundantes relacionados, y luego crear las carpetas más básicas en el proyecto.

  • carpeta api para solicitudes de red
  • La carpeta de activos se utiliza para almacenar algunos recursos estáticos, como iconos e imágenes.
  • carpeta de paginas para paginas
  • carpeta de componentes para componentes reutilizables

  Los directorios de archivos más detallados son los siguientes:

imagen.png

Instalación de dependencia

  相关文件夹配置完成后,可以开始安装项目需要的依赖

  • 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   用于添加多个类名

  安装成功后如下所示:

imagen.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}

imagen.png

  • 若出现某个页面跳转后不显示底部导航栏,可以通过简单的条件判断和{useLocation}接受传来的值来实现。比如如下所示:
import {useLocation} from 'react-router-dom'

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

数据请求

  在此项目中采用的是fastmock来请求与管理数据,然后在api文件夹中创建request.js来获取数据。后续在相关页面中引入即可。

imagen.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 (
    <FooterWrapper>
      <Link to="/" className={classnames({active:pathname == '/'})}>
      <span>首页</span>
      </Link>
      <Link to="/shop" className={classnames({active:pathname == '/shop'})}>
      <span>商城</span>
      </Link>
      <Link to="/choose" className={classnames({active:pathname == '/choose'})}>
      <span><i className="iconfont icon-Addtianjia3"></i></span>
      </Link>
      <Link to="/message" className={classnames({active:pathname == '/message'})}>
      <Badge content='5'><span>消息</span></Badge>
      </Link>
      <Link to="/mine" className={classnames({active:pathname == '/mine'})}>
      <span>我</span></Link>
    </FooterWrapper>
  )
}

export default Footer

  主页面引入Footer,部分源码如下:

<>
<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>
<Footer />
</>

顶部导航栏

QQ录屏20220705171330.gif


  La barra de navegación superior utiliza la barra de pestañas para cambiar de contenido. Hay dos barras de navegación aquí, y también hay una barra de navegación debajo de la página de descubrimiento, por lo que debe implementar el efecto de la barra de navegación dos veces. La implementación de las dos barras de navegación es muy sencilla, el código fuente es el siguiente:
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(
        <div>
            <Tabs defaultActiveKey='find' style={
                {'--active-line-color':'#ed2b43','--active-title-color':'#000000'}}>
                <Tabs.Tab title='关注' key='care'>
                    <Care/>
                </Tabs.Tab>
                <Tabs.Tab title='发现' key='find'>
                    <Find/>
                </Tabs.Tab>
                <Tabs.Tab title='城市' key='city'>
                    <City/>
                </Tabs.Tab>
            </Tabs> 
            
            <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

Buscar.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

  La barra de pestañas en este proyecto usa la barra de pestañas empaquetada en antd-mobile, consulte la documentación en antd-mobile y luego introduzca los componentes relevantes, puede usarla. Aunque es más cómodo de usar, por tratarse de un componente empaquetado, la modificación de algunos estilos será más limitada. Para modificar el estilo, puede consultar el documento para modificar el estilo relacionado o agregar el nombre de clase className para redefinir el estilo relacionado. El sitio web relevante se adjunta a continuación. Los amigos interesados ​​pueden consultar los documentos relevantes. Esta es una buena biblioteca de componentes de interfaz de usuario.
Hormiga Diseño Móvil - Hormiga Diseño Móvil

Contenido para el hogar

QQ录屏20220705164119.gif


  La página de inicio es la página principal de este proyecto. Después de ingresar a esta página, se pueden realizar funciones relacionadas, como el salto de página. Los datos en la página se almacenan en fastmock. Luego, en las páginas Recomendar y Alimentos, los datos requeridos se obtienen en la página atravesando. Además, vaya a la página de búsqueda, y el cuadro de búsqueda que se usa en ella también es la Búsqueda empaquetada en antd-mobile. Puede modificar el estilo ligeramente y luego llamarlo directamente. Para los íconos, usar íconos de iconfont es suficiente para la mayoría de las necesidades. Introduzca la carpeta de fuentes con los íconos agregados de antemano en la carpeta de activos, y luego podrá modificar fácilmente el estilo del ícono en la carpeta de fuentes. Parte del código fuente es el siguiente:

Buscar.jsx

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

 const Search = () =>{
    return(
        <div>
            <Link to='/shop'>
           <NavBar>
                <SearchBar 
                className="searchbar"
                placeholder='请输入内容'
                style={{
                    '--border-radius': '100px',
                    '--background': '#f5f5f5',
                    '--height': '30px',
                    '--placeholder-color':'#afafaf',    
                }}
                />
                <span className="search">搜索</span>
            </NavBar>
            </Link>
        </div>
    )
 }

 export default Search

Recomendar.jsx

import React from "react";
import './style.css'

 const Recommend = ({source}) =>{
    const {img,content,author,icon} = source  
    return(
        <div className="List">
          <img src={img} className="list-img" />
          <div className="list-content">{content}</div>
          <div className="list-author">
            <img src={icon} className="icon-img"></img>
            <div className="list-h">{author}</div>
            <i className="iconfont icon-dianzan"></i>
          </div>
        </div>
    )
 }

 export default Recommend

Alimentos.jsx

import React from "react";
import './style.css'

 const Food = ({entry}) =>{
    const {img,content,author,icon} = entry  
    return(
        <div className="List">
          <img src={img} className="list-img" />
          <div className="list-content">{content}</div>
          <div className="list-author">
            <img src={icon} className="icon-img"></img>
            <div className="list-h">{author}</div>
            <i className="iconfont icon-dianzan"></i>
          </div>
        </div>
    )
 }

 export default Food

Resumir

  Este es un proyecto preliminar. Hay muchas funciones y componentes relacionados que no se han realizado completamente. Posteriormente, con el estudio profundo y el dominio del conocimiento de React , este proyecto se modificará y mejorará, y se seguirá publicando. Si hay optimizaciones o errores, puede señalarlos en el área de comentarios. Finalmente, si este artículo te puede ayudar, gracias por tus Me gusta ღ( ´・ᴗ・` )

Supongo que te gusta

Origin juejin.im/post/7116817540055040013
Recomendado
Clasificación