效果:
React\airbib\src\assets\svg\icon-arrow-left.jsx
svg 左图标
import React, { memo } from 'react'
import styleStrToObj from './utils'
const IconArrowLeft = memo((props) => {
const {width=12,height=12} = props
return (
<svg viewBox="0 0 18 18" role="img" aria-hidden="false" aria-label="previous" focusable="false" style={styleStrToObj(`height: ${height}px; width: ${width}px; display: block; fill: currentcolor;`)}><path d="m13.7 16.29a1 1 0 1 1 -1.42 1.41l-8-8a1 1 0 0 1 0-1.41l8-8a1 1 0 1 1 1.42 1.41l-7.29 7.29z" fillRule="evenodd"></path></svg>
)
})
export default IconArrowLeft
svg 右图标
import React, { memo } from 'react'
import styleStrToObj from './utils'
const IconArrowRight = memo((props) => {
const {width=12,height=12} = props
return (
<svg viewBox="0 0 18 18" role="img" aria-hidden="false" aria-label="next" focusable="false" style={styleStrToObj(`height: ${height}px; width: ${width}px; display: block; fill: currentcolor;`)}><path d="m4.29 1.71a1 1 0 1 1 1.42-1.41l8 8a1 1 0 0 1 0 1.41l-8 8a1 1 0 1 1 -1.42-1.41l7.29-7.29z" fillRule="evenodd"></path></svg>
)
})
export default IconArrowRight
React\airbib\src\components\room-item\index.jsx
import IconArrowLeft from '@/assets/svg/icon-arrow-left';
import IconArrowRight from '@/assets/svg/icon-arrow-right';
import Rating from '@material-ui/lab/Rating'; // 只能用 4.0版本
import { Carousel } from 'antd';
// import { Rating } from '@mui/material'
import PropTypes from 'prop-types'
import React, { memo, useRef } from 'react'
import {ItemWrapper} from './style'
const RoomItem = memo((props) => {
const {itemData,itemWidth="25%"} = props
const sliderRef = useRef()
function controlClickHandle(isRight = true) {
isRight ? sliderRef.current.next() : sliderRef.current.prev()
}
return (
<ItemWrapper
verifyColor={itemData?.verify_info.text_colo || "#39576a"}
itemWidth={itemWidth}
>
<div className='inner'>
{/* <div className='cover'>
<img src={itemData.picture_url} alt="" />
</div> */}
{/* 轮播图 */}
<div className='slider'>
<div className='control'>
<div className='btn left' onClick={e=>controlClickHandle(false)}>
<IconArrowLeft width='30' height='30'/>
</div>
<div className='btn right' onClick={e=>controlClickHandle(true)}>
<IconArrowRight width='30' height='30'/>
</div>
</div>
<Carousel dots={false} ref={sliderRef}>
{
itemData?.picture_urls?.map(item =>{
return (
<div className='cover' key="item">
<img src={item} alt="" />
</div>
)
})
}
</Carousel>
</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={2.5} precision={0.2} readOnly sx={{fontSize:"12px",color:"#00848a", marginRight:"-1px"}}/> */}
<Rating value={2.5} precision={0.2} readOnly size="small" />
<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,
itemWidth:PropTypes.string
}
export default RoomItem
React\airbib\src\components\room-item\style.js
import styled from "styled-components";
export const ItemWrapper = styled.div`
flex-shrink: 0;
box-sizing: border-box;
width: ${props => props.itemWidth};
padding: 8px;
.inner {
width: 100%;
}
.cover {
position: relative;
box-sizing: border-box;
padding: 66.66% 8px 0;
border-radius: 3px;
overflow: hidden;
img {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
}
// 轮播图样式
.slider{
position: relative;
cursor: pointer;
&:hover{
.control{
display: flex;
}
}
.control{
position: absolute;
z-index: 1;
left: 0;
right: 0;
top: 0;
bottom: 0;
display: none;
justify-content: space-between;
color: #fff;
.btn{
display: flex;
justify-content: center;
align-items: center;
width: 83px;
height: 100%;
background: linear-gradient(to left, transparent 0%, rgba(0,0,0,.25) 100%);
&.right{
background: linear-gradient(to right,transparent 0%, rgba(0,0,0,.25) 100%);
}
}
}
}
.desc {
margin: 10px 0 5px;
font-size: 12px;
font-weight: 700;
color: ${props => props.verifyColor};
}
.name {
font-size: 16px;
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.price {
margin: 8px 0;
}
.bottom {
display: flex;
align-items: center;
font-size: 12px;
font-weight: 600;
color: ${props => props.theme.text.primaryColor};
.count {
margin: 0 2px 0 4px;
}
.MuiRating-decimal {
margin-right: -2px;
}
}
`