React仿小米商城,雷总用了都说好!

345 阅读3分钟

前言

由于React的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来Web开发的主流工具。这个项目本身也越滚越大,从最早的UI引擎变成了一整套前后端通吃的Web App解决方案。衍生的React Native项目,目标更是宏伟,希望用写Web App的方式去写Native App。如果能够实现,整个互联网行业都会被颠覆,因为同一组人只需要写一次UI ,就能同时运行在服务器、浏览器和手机。下面是本人与大家分享的一个react项目,希望对各位有所帮助。

页面展示

image.png

扩展介绍

  • swiper是一款轻量级的轮播图插件,不仅支持pc端更是为移动端而生,用它可以快速地做出一个轮播图,或者扩展使其做出复杂的轮播效果。
  • Axios 是一个基于 promise 的 HTTP 库,简单的讲就是可以发送get、post请求。
  • styled-components是react的一个第三方库,一种css私有化的方式。. 用来实现 CSS in JS 的方式之一。多人协作时,类名有概率会发生冲突,而 style-components可以生成hash类名,hash类名按内容生成,不会重复。
  • classnames 可以给元素添加多个类名

目录介绍

image.png

  • api 所有的接口都在这个文件夹中
  • assets 放置静态资源 如图片/字体图标/全局样式
  • components 放置公用组件
  • pages 放置主页面

二级路由

二级路由我使用的是NavLink,NavLink是Link的一个特定版本,会在匹配上当前的url的时候给已经渲染的元素添加参数,组件的属性有

  • activeClassName(string):设置选中样式,默认值为active
  • activeStyle(object):当元素被选中时,为此元素添加样式
  • exact(bool):为true时,只有当导致和完全匹配class和style才会应用
  • strict(bool):为true时,在确定为位置是否与当前URL匹配时,将考虑位置pathname后的斜线
  • isActive(func)判断链接是否激活的额外逻辑的功能
         <Tab>
            <NavLink to="/recommend">
                <TabItem>
                    <span>推荐</span>
                </TabItem>
            </NavLink>
            <NavLink to="/intelligent">
                <TabItem>
                    <span>智能</span>
                </TabItem>
            </NavLink>
            <NavLink to="/appliances">
                <TabItem>
                    <span>家电</span>
                </TabItem>
            </NavLink>
            <NavLink to="/phone">
                <TabItem>
                    <span>手机</span>
                </TabItem>
            </NavLink>
            <NavLink to="/notebook">
                <TabItem>
                    <span>笔记本</span>
                </TabItem>
            </NavLink>
        </Tab>

chrome-capture-2022-6-1.gif

轮播图

  useEffect(() => {
    new Swiper('.home_info_banners', {
        loop: true,
        autoplay: {
            delay: 3000
        }
    })
}, [])
     <div className="home_info_banners swiper-container">
            <div className="swiper-wrapper">
                    <div className = "swiper-slide">
                        <p>
                            <img width="100%" src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7948d1f963986b5f9dd240d32d6a0839.jpg?thumb=1&w=720&h=360" alt=""/>
                        </p>
                    </div>
                    <div className="swiper-slide">
                        <p>
                            <img width="100%" src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/3ceb285f512491956f67f83a6d2e821c.jpg?thumb=1&w=720&h=360" alt=""/>
                        </p>
                    </div>
                    <div className="swiper-slide">
                        <p>
                            <img width="100%" src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/d075c8f62b867bfdd9345f81107841e4.jpg?thumb=1&w=720&h=360" alt=""/>
                        </p>
                    </div>
            </div>
            <div className="swiper-pagination swiper-pagination-white swiper-pagination-bullets">
                    <span class="swiper-pagination-bullet"></span>
                    <span class="swiper-pagination-bullet"></span>
                    <span class="swiper-pagination-bullet"></span>
            </div>
        </div>

chrome-capture-2022-6-1 (2).gif

底部导航栏

底部导航栏是通过Link完成路由的跳转

    <FooterWrapper>
            <Link to="/home" className={classnames({active:pathname == '/home' || pathname == '/' })}>
                <i className="fa fa-home"></i>
                <span>首页</span>
            </Link>
            <Link to="/classify" className={classnames({active:pathname == '/classify'})}>
                <i className="fa fa-list"></i>
                <span>分类</span>
            </Link>
            <Link to="/miclub" className={classnames({active:pathname == '/miclub'})}>
                <i className="fa fa-globe"></i>
                <span>米圈</span>
            </Link>
            <Link to="/cart"  className={classnames({active:pathname == '/cart'})}>
                <i className="fa fa-shopping-cart"></i>
                <span>购物车</span>
            </Link>
            <Link to="/mine"  className={classnames({active:pathname == '/mine'})}>
                <i className="fa fa-user-o"></i>
                <span>我的</span>
            </Link>
        </FooterWrapper>

chrome-capture-2022-6-1 (1).gif

路由设置

image.png

路由可以专门搞个文件夹,使App.jsx界面更加简洁、美观,并且更换路由时更加方便,出现错误时也可以更快的定位

     <Routes>
        <Route path="/" element={<Home />}></Route>
        <Route path="/home" element={<Home />}></Route>
        <Route path="/recommend" element={<Recommend />}></Route>
            <Route path="/intelligent" element={<Intelligent />}></Route>
            <Route path="/appliances" element={<Appliances />}></Route>
            <Route path="/classify" element={<Classify />}></Route>
        <Route path="/miclub" element={<Miclub />}></Route>
        <Route path="/cart" element={<Shoppingcart />}></Route> 
        <Route path="/mine" element={<Mine />}></Route>
        <Route path="/search" element={<Search />}></Route>
      </Routes>

接口

后端数据是使用fask mock建立接口自己编写数据

接口代码展示

import axios from 'axios'

export const getCategory = () => 
    axios.get('https://www.fastmock.site/mock/576b4bbb319e22bfeea77454ada0e7b9/beers/category')

export const getCell = () => 
    axios.get('https://www.fastmock.site/mock/576b4bbb319e22bfeea77454ada0e7b9/beers/cell')

部分接口封装展示

   const [category, setCategory] = useState([])
    useEffect(() => {
        (async () => {
            let {data} = await getCell()
            setCategory(data)
        })()
    })
    const renderCategory = () => {
        return category.map(item => 
            <Link 
                to="/eleme/all"
                className="swiper-item"
                key={item.id}
                >
                <div>
                    <p>
                        <img src={item.img} />
                    </p>
                </div>
            </Link>
        )
    }

自适应设置

自适应就是在处理和分析过程中,根据处理数据的数据特征自动调整处理方法、处理顺序、处理参数、边界条件或约束条件,使其与所处理数据的统计分布特征、结构特征相适应,以取得最佳的处理效果的过程。自适应过程是一个不断逼近目标的过程,它所遵循的途径以数学模型表示,称为自适应。这个是网上找大佬的

var init = function () {
    var clientWidth = document.documentElement.clientWidth || document.body.clientWidth;
    if (clientWidth >= 640) {
      clientWidth = 640;
    }
    var fontSize = 20 / 375 * clientWidth;
    document.documentElement.style.fontSize = fontSize + "px";
  }
  
  init();
  
  window.addEventListener("resize", init);

总结

目前此项目还有些粗糙,并且由于时间问题,目前就写了这些板块,后续板块和一些功能都没有完善,以后会陆续完善此项目及其功能。 源码地址react/MiShop