React18项目,UI组件库的使用(Material UI),SectionRooms组件封装,

248 阅读2分钟

UI组件库的使用

image.png

  • 使用
import React, { memo } from "react";

import Button from "@mui/material/Button";
const Home = memo(() => {
  return (
        <div>
          <Button variant="contained">Hello World</Button>
        </div>
  );
});
export default Home;

Rating的使用

import PropTypes from "prop-types";
import React, { memo } from "react";
import { ItemWrapper } from "./style";

import Rating from "@mui/material/Rating";

const RoomItem = memo((props) => {
  const { itemData } = props;
  return (
    <ItemWrapper verifycolor={itemData?.verify_info?.text_color || "#39576a"}>
      <div className="inner">
        <div className="cover">
          <img src={itemData.picture_url} alt="" />
        </div>
        <div className="desc">{itemData.verify_info.messages.join("·")}</div>
        <div className="name">{itemData.name}</div>
        <div className="price">¥{itemData.price}/晚</div>
        <div className="bottom">
          <Rating
            value={itemData.star_rating ?? 5}
            precision={0.1}
            readOnly
            sx={{ fontSize: "12px", color: "#00848A" }}
          />
          <span className="count">{itemData.reviews_count}</span>
          {itemData?.bottom_info && <span className="extra">·{itemData?.bottom_info?.content}</span>}
        </div>
      </div>
    </ItemWrapper>
  );
});

RoomItem.propTypes = {
  itemData: PropTypes.object,
};
export default RoomItem;
import styled from "styled-components";

export const ItemWrapper = styled.div`
  width: 25%;
  padding: 8px;
  box-sizing: border-box;
  .inner {
    width: 100%;
  }
  .cover {
    position: relative;
    box-sizing: border-box;
    padding: 66.66% 8px 0;
    overflow: hidden;
    img {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
    }
  }
  .desc {
    margin: 10px 0 5px;
    font-size: 12px;
    font-weight: 700;
    /* color: #39576a; */
    color: ${(props) => props.verifycolor};
  }
  .name {
    font-size: 16px;
    font-weight: 700;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
  }
  .price {
    margin: 8px 0;
  }
  .bottom {
    display: flex;
    align-items: flex-start;
    font-size: 12px;
    font-weight: 600;
    color: ${(props) => props.theme.text.primary};
    .count {
      margin: 0 2px 0 4px;
    }
    .MuiRating-decimal {
      margin-right: -3px;
    }
  }
`;

Home组件:

import React, { memo, useEffect } from "react";
import { shallowEqual, useDispatch, useSelector } from "react-redux";

import { HomeWrapper } from "./style";
import HomeBanner from "./c-cpns/home-banner";
import { fetchHomeDataAction } from "@/store/modules/home";
import SectionHeader from "@/components/section-header";
import RoomItem from "@/components/room-item";

const Home = memo(() => {
  // 从redux获取数据
  const { goodPriceInfo } = useSelector(
    (state) => ({
      goodPriceInfo: state.home.goodPriceInfo,
    }),
    shallowEqual
  );

  // 派发异步的事件:发送网络请求
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(fetchHomeDataAction("传参数data"));
  }, [dispatch]);

  return (
    <HomeWrapper>
      {/* 轮播图 、banner图片*/}
      <HomeBanner />
      <div className="content">
        <div className="good-price">
          <SectionHeader title={goodPriceInfo.title} />
          <ul className="room-list">
            {goodPriceInfo.list?.slice(0, 8)?.map((item) => {
              return <RoomItem itemData={item} key={item.id} />;
            })}
          </ul>
        </div>
      </div>
    </HomeWrapper>
  );
});
export default Home;
import styled from "styled-components";

export const HomeWrapper = styled.div`
  .content {
    width: 1032px;
    margin: 0 auto;
    .good-price {
      margin-top: 30px;

      .room-list {
        display: flex;
        flex-wrap: wrap;
        margin: 0 -8px;
      }
    }
  }
`;

效果:

image.png

SectionRooms组件封装

对组件进行进一步抽取(ul部分):

image.png

import PropTypes from "prop-types";
import React, { memo } from "react";
import { RoomsWrapper } from "./style";
import RoomItem from "../room-item";

const SectionRooms = memo((props) => {
  const { roomList = [] } = props;

  return (
    <RoomsWrapper>
      {roomList?.slice(0, 8)?.map((item) => {
        return <RoomItem itemData={item} key={item.id} />;
      })}
    </RoomsWrapper>
  );
});

SectionRooms.propTypes = {
  roomList: PropTypes.array,
};
export default SectionRooms;
import styled from "styled-components";
export const RoomsWrapper = styled.div`
  display: flex;
  flex-wrap: wrap;
  margin: 0 -8px;
`;

Home组件中使用SectionRooms:

import React, { memo, useEffect } from "react";
import { shallowEqual, useDispatch, useSelector } from "react-redux";

import { HomeWrapper } from "./style";
import HomeBanner from "./c-cpns/home-banner";
import { fetchHomeDataAction } from "@/store/modules/home";
import SectionHeader from "@/components/section-header";
import SectionRooms from "@/components/section-rooms";

const Home = memo(() => {
  // 从redux获取数据
  const { goodPriceInfo } = useSelector(
    (state) => ({
      goodPriceInfo: state.home.goodPriceInfo,
    }),
    shallowEqual
  );

  // 派发异步的事件:发送网络请求
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(fetchHomeDataAction("传参数data"));
  }, [dispatch]);

  return (
    <HomeWrapper>
      {/* 轮播图 、banner图片*/}
      <HomeBanner />
      <div className="content">
        <div className="good-price">
          <SectionHeader title={goodPriceInfo.title} />
          {/* <ul className="room-list">
            {goodPriceInfo.list?.slice(0, 8)?.map((item) => {
              return <RoomItem itemData={item} key={item.id} />;
            })}
          </ul> */}
          <SectionRooms roomList={goodPriceInfo?.list} />
        </div>
      </div>
    </HomeWrapper>
  );
});
export default Home;

进行样式小小的调整: 效果一样:

image.png