在上一篇文章中,我已給出了圖片輪播1.0的源碼,這次,我打算用以前學過的react來實現這個代碼。能實現一種功能的代碼不能算作一個好的代碼,我認為,在能實現一種功能的基礎上還有非常好的維護性,以及擴展性才能進入好的代碼的行列。但是,奈何本人才初涉前端,react也才開始學,只是學了一些皮毛,所有今天只是談談怎樣用react實現圖片的功能而已,在維護性與復用性上就沒多大的考慮,畢竟這種事也是需要我多多練習的嘛。代碼實現的功能與上篇文章所介紹的圖片輪播功能一樣。這里還是給出展示效果與功能吧。
展示效果如下:
功能:
點擊開始就開始播放圖片,點擊+0.5s或者-0.5s可調節播放速度。點擊左右箭頭切換上一張或者下一張圖片,鼠標移至圖片位置暫停播放,移出則繼續播放。下面原點有顏色處代表當前第幾張圖片,鼠標移至任意圓點都可使圖片切換到對應的圖片。
為什么要用react來寫:
在react中有一切皆組件的概念,這就使得代碼的復用性大大的加強了,而且,每個組件都有自己的狀態state,與父組件傳進來的數據props,這就使得代碼中存在變量污染問題就大大減小了。每個組件通過改變自己的state來自動重新渲染頁面,減少了我們的代碼量。其JSX的特點也使得代碼寫起來感覺比寫HTML好得多。當然,以上也只是我個人的感覺,如有問題還請多多包含。
寫代碼中也到的問題:
首先,是設計問題,怎樣來設計react的組件關系,哪些是父組件,哪些是該父組件的子組件。然后是state和props,組件中哪些數據應該是自己的state,哪些應該是從父組件中傳進來的數據props。
引進圖片的問題,在HTML中寫一個img標簽是這樣:
而在react中JSX中卻不行,要這樣:
這相當于將圖片的src的路徑取了一個別名為image3,在img標簽中這樣使用便行了:
然后第二個,就是改變樣式的問題,在圖片輪播這個項目中我需要改變的是下面的圓點的顏色,我使用的方法是這樣:先定義一個style變量:
在使用該變量:比如在span標簽中:<span style={style}>●</span>
最后便是理解問題了,比如this指針傻傻分不清,以至于自己寫的代碼中,為什么這個地方要使用this,為什么要bing(this),以及為什么這里要用箭頭函數,我都是不一定說得出來。如果有哪位能為我解讀一二我是非常高興的。
源碼:
PlayImgApp:
import React,{Component} from 'react'
import PlayImgBut from './PlayImgbut'
import PlayImage from './PlayImage'
import PlayPoints from './PlayImgPoints'
import StartBut from './startBut'
class PlayImgApp extends Component{
? ? constructor(){
? ? ? ? super();
? ? ? ? this.state = {
? ? ? ? ? ? nowImgNumber:0,
? ? ? ? ? ? isStart:false,
? ? ? ? ? ? playTime:2000,
? ? ? ? }
? ? }
? ? componentDidMount(){
? ? ? ? this.change = setInterval(()=>this.changeNum(),this.state.playTime);
? ? }
? ? handleStart(){
? ? ? ? if(this.state.isStart){
? ? ? ? ? ? this.change = setInterval(()=>this.changeNum(),this.state.playTime);
? ? ? ? }else{
? ? ? ? ? ? clearInterval(this.change);
? ? ? ? }
? ? ? ? this.setState({
? ? ? ? ? ? isStart:!this.state.isStart,
? ? ? ? })
? ? }
? ? changeNum(){
? ? ? ? if(this.state.nowImgNumber == 5){
? ? ? ? ? ? this.setState({
? ? ? ? ? ? ? ? nowImgNumber:0,
? ? ? ? ? ? })
? ? ? ? }else{
? ? ? ? ? ? this.setState({
? ? ? ? ? ? ? ? nowImgNumber:this.state.nowImgNumber+1,
? ? ? ? ? ? })
? ? ? ? }
? ? }
? ? handleSubmit = (flag)=>{
? ? ? ? clearInterval(this.change);
? ? ? ? if(flag == 1) {
? ? ? ? ? ? if (this.state.nowImgNumber == 5) {
? ? ? ? ? ? ? ? this.setState({
? ? ? ? ? ? ? ? ? ? nowImgNumber: 0,
? ? ? ? ? ? ? ? ? ? isStart:false,
? ? ? ? ? ? ? ? })
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? this.setState({
? ? ? ? ? ? ? ? ? ? nowImgNumber: this.state.nowImgNumber + 1,
? ? ? ? ? ? ? ? ? ? isStart:false,
? ? ? ? ? ? ? ? })
? ? ? ? ? ? }
? ? ? ? }else{
? ? ? ? ? ? if (this.state.nowImgNumber == 0) {
? ? ? ? ? ? ? ? this.setState({
? ? ? ? ? ? ? ? ? ? nowImgNumber: 5,
? ? ? ? ? ? ? ? ? ? isStart:false,
? ? ? ? ? ? ? ? })
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? this.setState({
? ? ? ? ? ? ? ? ? ? nowImgNumber: this.state.nowImgNumber - 1,
? ? ? ? ? ? ? ? ? ? isStart:false,
? ? ? ? ? ? ? ? })
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? this.change = setInterval(()=>this.changeNum(),this.state.playTime);
? ? }
? ? handlePoint = (idNum)=>{
? ? ? ? clearInterval(this.change);
? ? ? ? this.setState({
? ? ? ? ? ? nowImgNumber:idNum,
? ? ? ? ? ? isStart:false,
? ? ? ? })
? ? }
? ? handlePointStart = ()=>{
? ? ? ? this.change = setInterval(()=>this.changeNum(),this.state.playTime);
? ? }
? ? componentWillUnmount(){
? ? ? ? clearInterval(this.change);
? ? }
? ? reviseTime = (time)=>{
? ? ? ? clearInterval(this.change);
? ? ? ? this.setState({
? ? ? ? ? ? playTime:this.state.playTime+time,
? ? ? ? })
? ? ? ? this.change = setInterval(()=>this.changeNum(),this.state.playTime + time);
? ? }
? ? render(){
? ? ? ? return(
? ? ? ? ? ? <div id='ImgApp'>
? ? ? ? ? ? ? ? <PlayImage num={this.state.nowImgNumber}/>
? ? ? ? ? ? ? ? <PlayImgBut id='leftB' value='<' onSubmit={this.handleSubmit}/>
? ? ? ? ? ? ? ? <PlayImgBut id='rightB' value='>' onSubmit={this.handleSubmit}/>
? ? ? ? ? ? ? ? <PlayPoints num={this.state.nowImgNumber} onPoint={this.handlePoint} start={this.handlePointStart}/>
? ? ? ? ? ? ? ? <StartBut onStart={this.handleStart.bind(this)} isStart={this.state.isStart} reviseTime={this.reviseTime} nowTime={this.state.playTime}/>
? ? ? ? ? ? </div>
? ? ? ? )
? ? }
}
export default PlayImgApp;
PlayImgBut:
import React,{Component} from 'react'
class PlayImgBut extends Component{
? ? handleSubmit = ()=>{
? ? ? ? if(this.props.onSubmit){
? ? ? ? ? ? if(this.props.value == '>'){
? ? ? ? ? ? ? ? this.props.onSubmit(1);
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? this.props.onSubmit(0)
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? render(){
? ? ? ? return(
? ? ? ? ? ? <a href='#'><div id={this.props.id} onClick={this.handleSubmit}>{this.props.value}</div></a>
? ? ? ? )
? ? }
}
export default PlayImgBut
PlayImgPoints:
import React,{Component} from 'react'
import PImgPoint from './PImgPoint'
class PlayImgPoints extends Component{
? ? createLi = ()=>{
? ? ? ? let array = [];
? ? ? ? for(let i = 0;i < 6;i++){
? ? ? ? ? ? if(i == this.props.num){
? ? ? ? ? ? ? ? let style =? {color:'deepskyblue'};
? ? ? ? ? ? ? ? array.push(<PImgPoint key={i} style={style} id={i} onPoint={this.props.onPoint} start={this.props.start}/>);
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? let style =? {color:'black'}
? ? ? ? ? ? ? ? array.push(<PImgPoint key={i} style={style} id={i} onPoint={this.props.onPoint} start={this.props.start}/>);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return array;
? ? }
? ? render(){
? ? ? ? return(
? ? ? ? ? ? <div className='points'>
? ? ? ? ? ? ? ? {this.createLi()}
? ? ? ? ? ? </div>
? ? ? ? )
? ? }
}
export default PlayImgPoints;
PImgPoint:
import React,{Component} from 'react'
class PImgPoint extends Component{
? ? handlePoint = ()=>{
? ? ? ? if(this.props.onPoint){
? ? ? ? ? ? this.props.onPoint(this.props.id);
? ? ? ? }
? ? }
? ? reStart = ()=>{
? ? ? ? if(this.props.start){
? ? ? ? ? ? this.props.start();
? ? ? ? }
}
? ? render(){
? ? ? ? return(
? ? ? ? ? ? <a href='#' color='blue'><span id={this.props.id} className='point' style={this.props.style} onMouseOver={this.handlePoint} onMouseOut={this.reStart}>●</span></a>
? ? ? ? )
? ? }
}
export default PImgPoint;
index:
import React from 'react'
import ReactDOM from 'react-dom'
import PlayImgApp from './PlayImgApp'
import {createStore} from 'redux'
import App from './App'
import './PlayImage.css'
ReactDOM.render(
? ? <PlayImgApp/>,
? ? document.getElementById('root')
);
PlayImage:
import React,{Component} from 'react'
import image1 from './img/1.jpg'
import image2 from './img/2.jpg'
import image3 from './img/3.jpg'
import image4 from './img/4.jpg'
import image5 from './img/5.jpg'
import image6 from './img/6.jpg'
class PlayImage extends Component{
? ? render(){
? ? ? ? let images = [image1,image2,image3,image4,image5,image6]
? ? ? ? const src = 'img/'+this.props.num+'.jpg';
? ? ? ? return(
? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? <img className='graph' src={images[this.props.num]}/>
? ? ? ? ? ? ? ? <img src={image3}/>
? ? ? ? ? ? </div>
? ? ? ? )
? ? }
}
export default PlayImage;
StartBut:
import React,{Component} from 'react'
class StartBut extends Component{
? ? handleStart=()=>{
? ? ? ? if(this.props.onStart){
? ? ? ? ? ? this.props.onStart();
? ? ? ? }
? ? }
? ? addPlayTime=(flag)=>{
? ? ? ? if(this.props.reviseTime){
? ? ? ? ? ? if(this.props.nowTime != 5000){
? ? ? ? ? ? ? ? this.props.reviseTime(+500)
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? reducePlayTime=()=>{
? ? ? ? if(this.props.reviseTime){
? ? ? ? ? ? if(this.props.nowTime != 0){
? ? ? ? ? ? ? ? this.props.reviseTime(-500)
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? render(){
? ? ? ? return(
? ? ? ? ? ? <div >
? ? ? ? ? ? ? ? <div id='isPlay' onClick={this.handleStart}>
? ? ? ? ? ? ? ? ? ? <a href='#'>{this.props.isStart?'開始':'暫停'}</a>
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? ? ? <span className="controlTime">當前圖片切換時間間隔為</span>
? ? ? ? ? ? ? ? ? ? <span className="controlTime" id="showTime">{this.props.nowTime/1000}</span>
? ? ? ? ? ? ? ? ? ? <span className="controlTime">秒</span>
? ? ? ? ? ? ? ? ? ? <a href="#" id="reduce" onClick={this.reducePlayTime}><span className="controlTime" id="controlReduce">-0.5s</span></a>
? ? ? ? ? ? ? ? ? ? <a href="#" id="add" onClick={this.addPlayTime}><span className="controlTime" id="controlAdd">+0.5s</span></a>
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? </div>
? ? ? ? )
? ? }
}
export default StartBut;
PlayImage.css:
body{
? ? background-color: #e6e6e6;
}
a{
? ? text-decoration: none;
? ? color: black;
}
#ImgApp{
? ? margin: auto;
? ? margin-top: 50px;
? ? width: 60%;
? ? height: 600px;
? ? background-color: white;
? ? border: solid 1px black;
? ? border-radius: 5px/5px;
? ? text-align: center;
}
.graph{
? ? margin-top: 30px;
? ? width: 80%;
? ? height: 480px;
? ? border-radius: 8px/8px;
}
#leftB,#rightB{
? ? font-size: 80px;
? ? position: absolute;
? ? top: 35%;
? ? color: black;
}
#leftB {
}
#rightB{
? ? right: +20%;
}
#leftB:hover,#rightB:hover{
? ? background-color: lightgray;
? ? border-radius:5px/5px;
}
#leftB:active,#rightB:active{
? ? background-color: darkgray;
? ? border-radius:5px/5px;
}
.points{
? ? letter-spacing: 40px;
? ? margin-top: 20px;
}
#isPlay{
? ? float:right;
? ? display: inline-block;
? ? margin-right: 10px;
? ? font-size: 20px;
? ? border: solid 3px deepskyblue;
? ? border-radius: 3px/3px;
? ? width: 3em;
? ? height: 30px;
? ? line-height: 30px;
}
#isPlay:hover{
? ? background-color: deepskyblue;
}
#isPlay:active{
? ? background-color: dodgerblue;
}
.controlTime{
? ? word-spacing: 10px;
? ? font-size: 30px;
? ? margin-bottom: 5px;
}
#controlAdd,#controlReduce{
? ? display: inline-block;
? ? border: solid 2px black;
? ? border-radius: 5px/5px;
? ? width: 90px;
}