React开发第一个组件-仿小红书商品展示组件
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
简介
React作为进击大厂必学的框架技术,传统的代码思想需要手动修改DOM对象,对浏览器的性能产生巨大的问题。框架就能很好的解决一些问题。以声明式编程和组件化开发为理念框架尤为重要。接下来我们以组件化开发思想来通过实战小红书商品展示功能,介绍我的思路以及方法,希望对前端朋友们的react学习有帮助。
- [技术使用方面]
- 前端三剑客
Html.css.javascript React Hooks全家桶ant design-mobile非常好用的框架styled-components样式设计axios+fastmock数据请求方式
- 前端三剑客
正文
我们先来看看组件实现后的效果吧:
- 组件设计思路
- 头部搜索组件:静态组件的实现,后面扩展购物车组件实现
- 底部路由导航组件:通过路由的跳转实现单页面的切换效果
- 轮播图组件:使用swiper包,实现轮播效果
- 分类选择组件:静态组件的实现
- 商品展示组件:在父组件的请求数据,通过props传递数据给子组件
- 商品详情组件:点击不同的商品组件,在详情页面展示不同的数据 接下来看整个项目的目录结构
- 路由的实现效果 点击导航栏选择不同的页面展示,共为五个导航模块
配置路由跳转组件,通过对<Link/>一个路径,在<Route/>匹配路径,选择不同的组件进行跳转。
import { useState } from 'react'
import logo from './logo.svg'
import './App.css'
import {Routes,Route,Router,useParams} from 'react-router-dom'
import Footer from './components/Footer'
import Home from './pages/Home'
import Shop from './pages/Shop'
import Add from './pages/Add'
import Mine from './pages/Mine'
import Order from './pages/Order'
import Follow from './pages/Home/Follow'
import Find from './pages/Home/Find'
import Native from './pages/Home/Native'
import Detail from './components/Detail'
function App() {
return (
<div className="App">
<Routes>
<Route path='/' element={<Home/>} />
<Route path='/home' element={<Home/>} >
<Route path='/home/follow' element={<Follow/>}/>
<Route path='/home/find' element={<Find/>}/>
<Route path='/home/native' element={<Native/>}/>
</Route>
<Route path='/shop' element={<Shop/>} />
<Route path='/add' element={<Add/>} />
<Route path='/mine' element={<Mine/>} />
<Route path='/order' element={<Order/>} />
<Route path='/detail' element={<Detail/>}/>
</Routes>
<Footer/>
</div>
)
}
export default App
底部导航,点击不同选项,样式添加
<Link to="/home" className={classnames({active:pathname == '/home' || pathname == '/' })}>
<i className="fa fa-home"></i>
<span>首页</span>
</Link>
<Link to="/shop" className={classnames({active:pathname == '/shop'})}>
<i className="fa fa-shopping-bag"></i>
<span>购物</span>
</Link>
<Link to="/add" className={classnames({add:true})}>
<i className="fa fa-plus-square-o fa-3x"></i>
</Link>
<Link to="/order" className={classnames({active:pathname == '/order'})}>
<i className="fa fa-book"></i>
<span>消息</span>
</Link>
<Link to="/mine" className={classnames({active:pathname == '/mine'})}>
<i className="fa fa-user"></i>
<span>我</span>
</Link>
这里在添加一个动态样式,下载classnames这个包,可以方便的添加多个样式,给需要改变样式一个boolean值,在通过获取当前页面路径第一个/后面的路径,比较相等的就添加样式,实现动态切换样式效果。
-
轮播组件实现 通过使用
swiper包的使用,实现轮播效果, 在父组件请求数据通过props传递给子组件数据进行展示。
实例一个swiper对象
useEffect(()=>{
new Swiper('.btn-banners',{
loop:true,
autoplay:{
delay:1000
}
})
})
数据遍历展示实现轮播效果
<div className="btn-banners swiper-container">
<div className="swiper-wrapper">
{
shop.map(item=>(
<div className="swiper-slide">
<img src={item.images} alt="" /> </div>
))
}
</div>
</div>
4.商品分类选择组件
写好组件的样式框架,在父组件获取数据,传递给子组件,进行数据展示
<div className="banners-slide">
{
banners.map(item=>(
<Link to='#' className='banners-item'>
<div>
<p>
<img src={item.iomages} alt="" />
</p>
<span>
{item.title}
</span>
</div>
</Link>
))
}
</div>
- 商品展示组件 作为一个功能组件,同样在父组件请求数据实现遍历渲染,再点击跳转到自己对应的商品详情页,传递自己的id找到对应的商品详情页。
<div className='shopinfo'>
{
shopinfo.map(item=>(
<Link
to={
{
pathname:'/detail',
search:`id=${item.id}`
}
}
key={item.id}
style={{display:'block'}}
>
<div className='shopinfo-box'>
<div>
<span>
<img src={item.images}alt="" />
</span>
</div>
<p>{item.title}</p>
<h3>{item.price}</h3>
</div>
</Link>
))
}
</div>
在这个组件通过<Link/>实现路由的跳转,给路由传参,传一个Id找到对应的自己的数据,在详情页面进行展示。
- 商品详情页面组件 在详情页面展示点击过来商品的详细信息,通过路由传递过来的id参数,再对请求过来的数据进行过滤,过滤出id相同的数据在页面展示
点击第一个商品展示:
点击第二个商品展示:
通过对请求的数据进行过滤出来对应数据
const [search] = useSearchParams()
const detailid= search.get('id') || ''
useEffect(()=>{
let detaildataa= detail.filter((item)=>
detailid == item.id
)
setDetaill(detaildataa)
},[detail])
通过请求过来的数据进行页面展示
<div className="btn-a btn-banners swiper-container">
<div className="swiper-wrapper">
{
detaill.length !==0 ? detaill[0].img.map((item)=>(
<div className="swiper-slide">
<img src={item} alt="" className='aimg'/>
</div>
)):''
}
</div>
</div>
<div className="detail-body">
<div className='s-a'>
<span>¥
<i>{detaill.length !==0 ? detaill[0].price:'' }</i>
</span>
<i className='fa fa-star-o'></i>
</div>
<div className='title'>
{detaill.length !==0 ? detaill[0].title:'' }
</div>
在页面展示处理的小细节,当请求数据时,刚开始给一个默认值,会使页面展示报错,因此添加一个判断功能,判断数组长度不为空时进行展示数据。以及在头部返回按钮,直接给按钮一个<Link to='/shop'/>跳转到商品展示页
最后
以上就是组件完成的全部内容了,在一些细节处理方面还有不足之处,尤其在页面的一些样式 ,后续还将持续更新。在一些功能方面,比如收藏,加入购物车,购买等功能的实现,后面尽快完善起来.