一、前言

本项目是为了给react新手入门做的一个仿星巴克菜单组件demo,假如能帮助到您,还请给一个小小的点赞

1.1、项目展现

手把手带你做一个React入门实战demo:星巴克菜单组件/移动端适配/Tab切换

githu动画制作软件b开源地址

gitee开源地址

1.1、能够学到的小常识

  1. 组件之间的传值(父传子,子传父)
  2. 切换navbar进行数据的挑选
  3. 移动端approve的不同机型适配(rem)
  4. SPA单页使用Footer的完成(还未完Go成除appearance菜单以外的组件)

二、项目目录建立

starbucks-demo
-> api
    ->request.js(处理接口数据)
-> assets
    ->reset.css(款式重置)
-> components
    ->emptylist
    ->footer
    ->listitem
    ->menu(完成路由跳转今后应该放在pages目录下)
    ->navbar
->public/js(完成移动端款式适配)

三、项目完成流程

3.0、技能涉及

  • WEUI中的Toast组件,数据未加载时,展现loading圈圈
  • axios合作fastmock,模拟从接口拿到数据的过程
  • styled-components:完成css in js,还能够完成css的嵌套,关于写款式十分方便
  • classna数组c语言mes:避免多类名appointment由于引号而不起动画片少儿小猪佩奇作用

3.1、切分页面组成及数据预备

1. 切分页面

  • 手把手带你做一个React入门实战demo:星巴克菜单组件/移动端适配/Tab切换
  • 这样一个menu组件,利用组件化的思维,咱们能够切分红TabBar,GoodItem,Footer这样三个组件
  • 所以咱们的页面组成应该如下
    <Wrapper>
        {/* 1.NavBar组件 */}
        <NavBar tab={tab} Fn={Fn}/>
        {/* 2.过渡动画Toast,没有数据的时分展现,引进了WEUI结构 */}
        {<Toast show={loading} icon="loading">加载中...</Toast>}
        {/* 2.ListItem产品展现组件*/}
        {menuList.length>0 ? <ListItem menuList={menuList}/> : <EmptyItem/>}
        {/* 3.frap查找按钮,没有封装成组件由于他固定在这儿,并且没有复用的时机*/}
        <div className="frap">
            <button id="featured-campaign-search" className="button_primary" rel="menu-search-overlay">查找菜单</button>
        </div>
    </Wrapper>
    

2. 数据预备

  • 你能够尝试访问这儿拿到接口的数据:www.fa工资超过5000怎么扣税stmock.site/mock/5321bf…

3.2、第一个组件:NavBar

  • 手把手带你做一个React入门实战demo:星巴克菜单组件/移动端适配/Tab切换

1. tab切换与款式改动

  • 这个组件要点在于操控tabs的切换给li标签加上actice款式,在点击事情的一起,经过履行父组件传过来的Fn函数,同步的改动父组宫颈癌件当中的tab特点(完成了子组件传父组件)

  • 这儿动画有一个小要点,为什么onClick函数需要用箭头函数?这是由于箭头函数不会绑定自己的this,假如不用箭头函数,咱们需要用bind手动绑定函数的this,不然onClick不会指向当时组件对象,假如你还需要传参数或许操控事情(approveevent)用箭头函数更佳。

  • 最终经过tab状况的改动与act工龄越长退休金越多吗ive类名相对应,完成MVVM

    //父组件Menu
    const [tab,setTab] = useState("悉数")
    const Fn = (tab) =>{
        setTab(tab)
    }
    <NavBar tab={tab} Fn={Fn}/>//这儿给NavBar传入了tab特点和Fn函数
    
    //子组件NavBar
    export default function NavBar(props) {
    const {tab,Fn} = props//从父组件Menu中解构出tab数据,Fn函数
    const changeTab = (tabname)=>{
        Fn && Fn(tabname);//履行点击事情的一起经过Fn函数将tab数据传回给Menu组件
    }
    return (
    <Wrapper>
        <nav className='nav-title'>菜单</nav>
        <div className="tabs-wrapper">
        <ul className='subcategories'>
            {/* onClick绑定li的tab状况修改,并经过Fn函数传至Menu组件完成MVVM */}
            <li className={tab=="悉数"?'active':""} onClick={()=>changeTab("悉数")}>悉数</li>
            <li className={tab=="饮料"?'active':""} onClick={()=>changeTab("饮料")}>饮料</li>
            <li className={tab=="美食"?'active':""} onClick={()=>changeTab("美食")}>美食</li>
            <li className={tab=="咖啡产品"?'active':""} onClick={()=>changeTab("咖啡产品")}>咖啡产品</li>
            <li className={tab=="产品"?'active':""} onClick={()=>changeTab("产品")}>产品</li>
        </ul>
        </div>
    </Wrapper>
            )
    
    //css
    li{
        display: inline-block;
        padding-top: 0.6rem;
        padding-bottom: 0.15rem;
        margin-right: 0.9rem;
    //&:父亲选择器,等同于li.active{}
    &.active{
        //点击下方小绿条的完成
        border-bottom: 0.15rem solid rgb(0, 168, 98);
        color: rgba(0, 0, 0, 0.87);
        font-weight: 700;
        transition: all 0.2s;
    }
    

2. 完成数据的过滤

  • 原本应后端需要学什么该放在menu组件讲的,但是为了文章节奏,咱们在这儿讲清楚数据的过滤。
  • 在文章3.0时,咱们从动画片汪汪队fas数组c语言tmock接口网站拿到了自界说的数据,接下来咱们需要在拿到数据的一起完成数据过滤
  • 后端经过axios.get得到的数appetite据的一起经过menu组件传过来动画专业tab特点值(由于现在只讲了后端NavBar组件,你也能够理解为NavBaappstorer中的数组去重方法tab特点,这两个在特点上是相同的)对数据数组进行filter操作
  • 要完成切换改动产品数组数据还有一步必不可少,要用useEf后端语言fect()去监听tab特点的改动,改动了就从头加载一次Go,后续men动画片小猪佩奇u组件咱们动画片小猪佩奇还会讲到
    import axios from 'axios'
    export const getMenuList = ({tab}) =>
    axios.get('https://www.fastmock.site/mock/5321bf649d06645c4266f3e0d45ae1cc/menu/all')
    .then ( list => {
      let remainlist=list.data;
      if(tab){
          switch(tab) {
              case "悉数":
                  remainlist=remainlist;
                  break;
              case "饮料":
                  remainlist=remainlist.filter(item => item.status==1);
                  break;
              case "美食":
                  remainlist=remainlist.filter(item => item.status==2);
                  break;
              case "咖啡产品":
                  remainlist=remainlist.filter(item => item.status==3);
                  break;
              case "产品":
                  remainlist=remainlist.filter(item => item.status==4);
                  break;
          default:
          break;
      }
    }
    return Promise.resolve({
          remainlist
          });
      }
    )
    

3.3、第二个组件:ListItem

  • 手把手带你做一个React入门实战demo:星巴克菜单组件/移动端适配/Tab切换
  • 这个组件的功用首要是完成接口数据的展现,并封装款式输出
  • 咱们能够在遍历的时分以组件Good的方式输出,动画片少儿小猪佩奇然后在Good组件中咱们能够更好的封装款式(首要用到弹性布局)
    import React from 'react'
    import { Wrapper,GoodWrapper } from './style'
    const Good = ({goodItem}) => (
    <GoodWrapper>
        <div className="good">
            <img src={goodItem.img} alt=""/>
            <div className="name">{goodItem.goods}</div>
        </div>
    </GoodWrapper>
    )
    export default function ListItem({menuList}) {
        return (
        //在遍历的时分以Good组件的方式遍历,去Good中丰富数据的款式
            <Wrapper>
            {
                    menuList.map(
                    (item)=>(
                    <Good goodItem={item} key={item.id}/>
                    )
                )
            }
            <div className="tips">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;实际产品以门店供应为准。</div>
            </Wrapper>
            )
    }
    

3.4、第三个组龚俊件:Footer后端语言

  • 手把手带你做一个React入门实战demo:星巴克菜单组件/移动端适配/Tab切换
  • 作为SP龚俊A中离后端不开的Footer组件,再未来路由动画片猫和老鼠跳转的功用中他的地位显著
  • 咱们经过react-router-do后端语言m中的useLocation,解构出pathname,经过url的改动画片少儿小猪佩奇变完成footer的图片切换
  • 例如当pathname=='/home'的时分,展现绿色img(icon),否动画片少儿小猪佩奇则展工龄越长退休金越多吗现白色的appear
  • c动画大放映lassnames能够用在需要多类名或许动态类名上,和NvBar的完成APP相同,都是为了完成动态类名后端开发假如没触摸过classnames能够看这儿classnames的运用
    import React 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 (
    <FooterWrapper>
       {/* 为了限制篇幅,这儿只展现了两个Link标签 */}
       <Link to="/account" className={classnames({active:pathname == '/account'})}>
           {pathname == '/account' ?
           <img src="https://www.6hu.cc/files/2022/07/41083-6iuJVl.svg" alt="" className='active'/>:
           <img src='https://www.6hu.cc/files/2022/07/41083-2MstZq.svg'/>
           }
           <span>我的账户</span>
       </Link>
       <Link to="/menu" className={classnames({active:pathname == '/menu'})}>
           {pathname == '/menu' ?
           <img src="https://www.6hu.cc/files/2022/07/41083-HcS4VM.svg" alt="" className='active'/>:
           <img src='https://www.6hu.cc/files/2022/07/41083-uaXTFs.svg'/>
           }
           <span>菜单</span>
       </Link>
    </FooterWrapper>
       )
    }
    

3.5、第四个组件:Menu

  • 为了进行标准的数据管理后端框架,咱们需要把状况变量都界说在Menu组件,经过父组件统一管理
  • Menu组件需要引进NabBar导航栏组件,ListItem产品组件,查找框(未封装为组件)
  • 数据状况首要有loading,menulist,t动画片少儿小猪佩奇ab
  • 运用UseEffect的第二个参数监听tab的改变,改变就从头履行一次useEffect内部的语句,完成NavBar工资超过5000怎么扣税的切换改动产品后端开发数组
    export default function Menu() {
    //菜单组件数据为0时,给weui的Toast组件设置为true
    const [loading,setLoading]=useState(false);
    //菜单组件,初始的时分为空,后续经过axios得到
    const [menuList,setMenuList] = useState([])
    //在NavBar中操控tab切换的状况
    const [tab,setTab] = useState("悉数")
    //这个函数会在NavBar中的tab切换后履行,并返回NavBar组件中的tab值
    const Fn = (tab) =>{
        setTab(tab)
    }
    //履行网络请求获取菜单,并且监听tab的改变,改变就从头加载
    useEffect(() => {
        //加载数据前设置Toast状况为true
        setLoading(true);
        (async()=>{
            const {remainlist} = await getMenuList({tab});
            setMenuList(remainlist)
        })()
        //加载数据后设置Toast状况未false
        setLoading(false)
    },[tab])
    return (
        <Wrapper>
            <NavBar tab={tab} Fn={Fn}/>
            {<Toast show={loading} icon="loading">加载中...</Toast>}
            {menuList.length>0 ? <ListItem menuList={menuList}/> : <EmptyItem/>}
            <div className="frap">
                <button id="featured-campaign-search" className="button_primary" rel="menu-search-overlay">查找菜单</button>
            </div>
        </Wrapper>
        )
    }
    

四、总结

4.1、回想开篇提到的小常识

4.2、组件之间approach的传值

1. 父传子

  • 如下所示
    //menu组件
    const [tab,setTab] = useState("悉数")
    <NavBar tab={tab}/>
    
    //NavBar组件,经过props参数解构出tab
    export default function NavBar(props) {
    const {tab} = props
    

2. 子传父

  • 本质上还是父传子,不过是子组件履行父组件函数,修改父组件数据特点
    //menu组件
    const [tab,setTab] = useState("悉数")
    const changeTab(tabname){
        setTab(tab)
    }
    <NavBar Fn={changeTab}/>
    
    //NavBar组件
    export default function NavBar(props) {
    const {tab,Fn} = props//得到Menu中界说的tab
    const changeTab = (tabname)=>{//点击事情履行Menu中的Fn函数
        Fn && Fn(tabname);
    }
    return (
    <Wrapper>
        <nav className='nav-title'>菜单</nav>
        <div className="tabs-wrapper">
            <ul className='subcategories'>
                <li className={tab=="悉数"?'active':""} onClick={()=>changeTab("悉数")}>悉数</li>
                <li className={tab=="饮料"?'active':""} onClick={()=>changeTab("饮料")}>饮料</li>
                <li className={tab=="美食"?'active':""} onClick={()=>changeTab("美食")}>美食</li>
                <li className={tab=="咖啡产品"?'active':""} onClick={()=>changeTab("咖啡产品")}>咖啡产品</li>
                <li className={tab=="产品"?'active':""} onClick={()=>changeTab("产品")}>产品</li>
            </ul>
        </div>
    </Wrapper>
    )
    }
    

3.工龄差一年工资差多少 兄弟组件传值

  • react中咱们一般不进行兄弟组件之间的传值,假如确实有这种情况,咱们会将数据的application数组提升
  • 例如a组件b组件是兄弟组件动画片少儿小猪佩奇,咱们将数据提升Goc组件c组件作为a,b组件的父组件,经过c组件传给a,b组件,转化为父子组件传google

4.3、切换navbar后端需要学什么行数据的挑选数组公式

  • 详见3.2

4.4、移动端的不同机型适配(rem)

1. 动态 REM 方案

  • 在运用单位操控页面元素巨细时,能够运用数组初始化固定单位px也能够运用相对单位 rem(相关于htmlfont-size巨细)。
  • 不同手宫颈癌机的font-size巨细不相同,切换设备时,假如用的是rem则会依照字体巨细来进行等份额缩放
  • 规划师交给的规划稿宽度一般是750px,规划稿上一个div的标注尺度是 375px(宽度是规划稿宽度的一半)
  • 然后再依照1rem=20px的份额,把所有px都换成rem完成移动端适配
    var init = function () {
    //获取当时html的宽度
    var clientWidth = document.documentElement.clientWidth || document.body.clientWidth;
    //移动端宽度假如超越640就依照640来算
    if (clientWidth >= 640) {
    clientWidth = 640;
    }
    //得到对应份额的fontsize,这样一个rem便是20px了
    var fontSize = 20 / 375 * clientWidth;
    document.documentElement.style.fontSize = fontSize + "px";
    }
    init();
    window.addEventListener("resize", init);
    

4.5、SPA单页使用Foote数组和链表的区别r的完成

  • 3.4approach的比较清晰了,款式能够直接去仓库拉取(能够数组公式后端是什么工作话给个staGor)。

五、结束

至此一个简略的starbucks菜单组件就到此为止公积金了,假如对您后端有帮助请费事点一个赞后端开发需要学什么且给项目一个star,后续更新路由及其他组件会再进行文章编辑。

github开源地动画片汪汪队

gitee开源地址

工龄差一年工资差多少正在参加技能社区创作者签约计划招募活动,点击链接报名投稿。