1.轮播图Banner组件
banner.js
// Carousel component
import React, { Component } from 'react';
import { Toast, Modal } from 'antd-mobile';
import './banner.less'
export default class Carousel extends Component {
constructor(props) {
super(props);
this.state = { currentIndex: 0,};
this.renderChildren = this.renderChildren.bind(this);
this.setIndex = this.setIndex.bind(this);
}
renderChildren() {
const { children,width, height } = this.props;
const childStyle = {
width: width,
height: height
};
return React.Children.map(children, child => {
const childClone = React.cloneElement(child, { style: childStyle });
return (
<div
style={{
display: 'inline-block'
}}
>
{childClone}
</div>
);
});
}
setIndex(index) {
const len = this.props.children.length;
console.log("length"+len);
const nextIndex = (index + len) % len;
this.setState({ currentIndex: nextIndex,});
}
handleTouchStart = (e) => {
this.startX = e.touches[0].clientX;
}
handleTouchMove = (e) => {
this.endX = e.touches[0].clientX;
}
handleTouchEnd = (e) => {
let distance = Math.abs(this.startX - this.endX);
let currentIndex = this.state.currentIndex;
if (distance > 50) {
if (this.startX > this.endX) {
this.setIndex(currentIndex - 1)
} else {
this.setIndex(currentIndex + 1)
}
}
}
render() {
const { width, height } = this.props;
const { currentIndex } = this.state;
const offset = -currentIndex * width;
const frameStyle = {
width: width,
height: height,
whiteSpace: 'nowrap',
overflow: 'hidden',
};
const imageRowStyle = {
marginLeft: offset,
transition: '.2s',
background: 'red',
};
return (
<div className="carousel">
<div className="frame" style={frameStyle}>
<div
onTouchStart={this.handleTouchStart}
onTouchMove={this.handleTouchMove}
onTouchEnd={this.handleTouchEnd}
// onClick={() => this.setIndex(currentIndex + 1)}
style={imageRowStyle}>{this.renderChildren()}
</div>
</div>
<div className="tag">
<p>{this.state.currentIndex+1}/{this.props.children.length}</p>
</div>
</div>
);
}
}
banner.less
.carousel {
position: relative;
}
.tag {
position: absolute;
width:4.44rem;
height:2.5rem;
background:rgba(0,0,0,1);
border-radius:1.25rem;
opacity:0.7;
justify-content: center;
right: 0.63rem;
bottom: 0.63rem;
p{
margin-top: 0.56rem;
font-size: 1.25rem;
line-height: 1.25rem;
text-align: center;
color: #ffffff;
}
}
用法
//轮播
import Carousel from '../../components/groupbuy/banner'
let imgs = [img1,img2,img3];
this.setState({
images: imgs,
})
<Carousel width={width} height={'18.75rem'} imageCount={images.length}>
{images.map(image => <img src={image} alt="" key={image}/>)}
</Carousel>
//注意:width 参与计算必须是数字,不能是rem单位,否则无法滑动:Example :width = 400
效果图:
2.拼团倒计时组件
1.countdown.js
import React, { Component } from 'react';
import './countDown.less'
class NoTimeContent extends Component {
constructor(props) {
super(props)
this.state = {
timeStamp:'',
day: 0,
hour: 0,
minute: 0,
second: 0
}
}
render() {
return (
<h2>
<span>
<span className="timeItem">
{this.state.day}
</span>
:
<span className="timeItem">
{this.state.hour}
</span>
:
<span className="timeItem">
{this.state.minute}
</span >
.
<span className="timeItem">
{this.state.second}
</span>
<span className="final">后结束</span></span>
</h2>
)
}
componentDidMount() {
//console.log("时间戳"+this.props.timeStamp);
let time = this.props.timeStamp;
const end = Date.parse(new Date(time))
this.countFun(end);
}
//卸载组件取消倒计时
componentWillUnmount(){
clearInterval(this.timer);
}
countFun = (end) => {
let now_time = Date.parse(new Date());
var remaining = end - now_time;
this.timer = setInterval(() => {
//防止出现负数
if (remaining > 1000) {
remaining -= 1000;
let day = Math.floor((remaining / 1000 / 3600) / 24);
let hour = Math.floor((remaining / 1000 / 3600) % 24);
let minute = Math.floor((remaining / 1000 / 60) % 60);
let second = Math.floor(remaining / 1000 % 60);
this.setState({
day:"0" + day,
hour:hour < 10 ? "0" + hour : hour,
minute:minute < 10 ? "0" + minute : minute,
second:second < 10 ? "0" + second : second
})
} else {
clearInterval(this.timer);
//倒计时结束时触发父组件的方法
//this.props.timeEnd();
}
}, 1000);
}
}
export default NoTimeContent;
2.countDown.less
h2 {
font-size: 0.88rem;
color: #FF1634;
.timeItem {
padding: 0.16rem;
width: 1.5rem;
height: 1rem;
background-color: #FF1634;
font-size: 0.88rem;
color: #FFFFFF;
border-radius: 0.25rem;
}
.final {
font-size: 1rem;
color: #515151;
}
}
3.用法
定义一个时间戳字符串,前提大于当前时间
time: '2019-5-29 24:00'
<NoTimeContent timeStamp={time}></NoTimeContent>
效果图
3.自定义Modal弹出框
ServiceDescriptionModal.js
import React, {Component} from 'react';
import './ServiceDescriptionModal.less'
import ReactDOM from 'react-dom';
import closeImg from '../../images/groupbuy/groupbuy_productDetail_closeBtn.png'
const styles = {
mask: {
position: 'fixed',
top: 0,
right: 0,
left: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.65)',
height: '100%',
zIndex: 1000,
},
modalWrap: {
position: 'fixed',
top: 0,
right: 0,
left: 0,
bottom: 0,
zIndex: 1000,
},
modal: {
fontSize: 14,
marginTop:'17.44rem',
width: '23.44rem',
height: '24.25rem',
backgroundColor: '#fff',
overflow: 'hidden',
borderTopRightRadius:'1rem',
borderTopLeftRadius:'1rem',
textAlign: 'center',
position: 'relative',
},
};
export default class ServiceDescriptionMask extends Component {
constructor (props) {
super(props);
this.modal = null;
}
componentDidMount () {
this.modal = document.createElement('div');
this.props.visible && document.body.appendChild(this.modal);
this._renderLayer();
}
componentDidUpdate () {
if (this.props.visible) {
document.body.appendChild(this.modal);
this._renderLayer();
} else {
this.modal.parentNode.removeChild(this.modal);
}
}
onOk = () => {
const { onOk } = this.props;
(onOk instanceof Function) && onOk();
}
// 渲染模态框内容
_renderLayer () {
const {title, content} = this.props;
let JSXdom = (
<div>
<div style={styles.mask} />
<div style={styles.modalWrap} onClick={this.onOk}>
<div style={styles.modal}>
<h2>{"服务说明"}</h2>
<div className="closeImg" onClick={this.onOk}>
<img src={closeImg} alt='' />
</div>
<div className="serviceItems">
<div className="item">
<div className="title">
{"关于成团"}
</div>
<div className="desc">
{"拼团时间内,未凑够人成团,已支付的费用将自动退回 "}
</div>
</div>
<div className="item">
<div className="title">
{"关于退费"}
</div>
<div className="desc">
{"拼团时间内,未凑够人成团,已支付的费用将自动退回 "}
</div>
</div>
<div className="item">
<div className="title">
{"关于有效期"}
</div>
<div className="desc">
{"购买商品或权益,一旦拼团成功,商品可永久收听,权益按购买时的说明使用 "}
</div>
</div>
<div className="item">
<div className="title">
{"关于解释权"}
</div>
<div className="desc">
{"呼呼收音机对本课程具有最终法律解释权 "}
</div>
</div>
</div>
</div>
</div>
</div>
);
ReactDOM.render(JSXdom, this.modal);
}
render () {
return null;
}
}
2.ServiceDescriptionModal.less
h2 {
margin-top: 1rem;
color: #515151;
font-size: 1.13rem;
}
.closeImg {
position: absolute;
top: 0.81rem;
right: 0.63rem;
img {
width: 1.88rem;
height: 1.88rem;
}
}
.serviceItems {
position: absolute;
top: 2.36rem;
width: 21.19rem;
height: 19.25rem;
margin: auto 1.13rem;
//background-color: red;
.item {
margin-top: 1.4rem;
line-height: 1.38rem;
text-align: left;
font-size: 1rem;
.title {
font-weight:bold;
}
}
}
3.使用
//服务说明Modal
import ServiceDescriptionMask from '../../components/groupbuy/ServiceDescriptionModal'
<div className="service">
<ServiceDescriptionMask visible={visible}
onOk={this.onOk} />
</div>
onOk = () => {
this.setState({
visible: false
})
}
onClick={this.showModal}
showModal = () => {
this.setState({
visible: true
})
}
效果图
4.消息上下轮播(拼团)
MessageCarousel.js
import React, { Component } from 'react';
import { Carousel } from 'antd-mobile';
import './MessageCarousel.less'
//图片资源
import addBg from '../../images/groupbuy/3.jpg'
class MessageMarquee extends Component {
constructor(props) {
super(props);
this.state = {
data: []
}
}
componentDidMount() {
this.requestList();
}
requestList = () => {
let temp = [{ id: "1", nickname: "Steven", robot: true }, { id: "2", nickname: "Lucy", robot: false }, { id: "3", nickname: "Benny", robot: true }];
this.setState({
data: temp
})
}
render() {
const { data } = this.state
console.log("data" + data);
return (
data && data.length > 0 ?
<div id="message-marquee">
<img src={addBg} alt="" />
<Carousel className="my-carousel"
vertical
dots={false}
dragging={false}
swiping={false}
autoplay
infinite
autoplayInterval={1500}
>
{
data.map((item, index) =>(
<div className="v-item" key={index}
style={{overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace:'nowrap'}}
>{item.nickname + ' '+ '1' + ' 小时前发起拼团'}</div>
))
}
</Carousel>
</div>
: ''
)
}
}
export default MessageMarquee;
MessageCarousel.css
#message-marquee {
position: absolute;
width:13.19rem;
height:2.5rem;
background:rgba(0,0,0,1);
border-radius:0.38rem;
opacity:0.7;
left: 0.63rem;
display: flex;
img{
float: left;
margin-left: 0.44rem;
margin-top: 0.44rem;
background-color:lightgray;
width: 1.63rem;
height: 1.63rem;
border-radius: 0.82rem;
}
.my-carousel{
margin-left: -0.56em;
padding:0 1rem;
width: 11.25rem;
//background: red;
font-size: 0.8rem;
text-align: left;
color: #FFFFFF;
line-height: 2.5rem;
flex: 1;
}
overflow: hidden;
}
使用
//消息轮播
import MessageMarquee from '../../components/groupbuy/MessageCarousel'
<div className="remindView">
<MessageMarquee/>
</div>
//less
.remindView {
position: absolute;
width:12.19rem;
height:2.5rem;
top: 2.56rem;
}
效果图
5.消息上下轮播(常规)
1.marquee.js
import React, { Component } from 'react';
import { Carousel } from 'antd-mobile';
import { getMarquee } from '../../api/hcFission'
class Marquee extends Component {
constructor(props) {
super(props);
this.state = {
data: []
}
}
componentDidMount() {
this.requestList();
}
requestList = () => {
getMarquee({}).then((res)=>{
this.setState({
data: res
})
})
}
render() {
const { data } = this.state
return (
data && data.length > 0 ?
<Carousel className="my-carousel"
vertical
dots={false}
dragging={false}
swiping={false}
style= {{height: '2.19rem',background: '#5A19B5', fontSize:'1rem', color: '#FFFFFF', padding:'0 1rem', lineHeight: '2.19rem'}}
autoplay
infinite
autoplayInterval={1500}
>
{
data.map((item, index) =>(
<div className="v-item" key={index}
style={{overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace:'nowrap'}}
>{'恭喜 ' + item.nickname + ':' + item.content}</div>
))
}
</Carousel> : ''
)
}
}
export default Marquee;
2.使用
//消息上下轮播常规
import Marquee from '../../components/HcFission/marquee'
//使用
<Marquee/>
效果图
转载于:https://www.jianshu.com/p/9eab07f72658