zoukankan      html  css  js  c++  java
  • 使用scss + react + webpack + es6实现幻灯片

    写在前面:

    刚学习完慕课网里的一个幻灯片案例,自己加了刚学的react,两者结合。首先让大家看看效果 点击此处 

    你可以先用纯js实现上面的效果:我的github上的 JS代码 或者 观看慕课提供的课程。再趁热打铁加上react

    React分析

    JS实现

    对于js来说,下面按钮一点击,就能根据当前的索引为按钮和图片绑定对应好的样式:取到对应的DOM元素,加上定义好的样式名,就能实现绑定效果。

    React实现

    但对于React来说,组件化开发的思想,可不是取得DOM元素就了事,因为React设计的初衷就是为了摆脱DOM。

    那对于这个Demo,如何实现点击按钮,上面的图片对应着变化呢?

    这个Demo拆成两个组件,一个图片组件,一个按钮。两个组件共用一个属性库,这就解决问题了。只要属性库的值变化,两个组件就都跟着变化

    因为这里只有一个状态,所以只要设置一个属性state.current,但要是应用复杂建议使用数组包含起来。

    首先看一下目录结构

    //---css   样式文件
    //---data
         //----imgDatas.json   存放图片信息json文件
    //---imgs    图片存放
    //---App.jsx  
    //---index.html
    //---main.js 
    //---package.json
    //---webpack.config.js

    接下来定义一下webpack.config.js

    var OpenBrowserPlugin = require('open-browser-webpack-plugin'); //自动打开浏览器
    var config={
        entry:'./main.js',     //入口文件
        output:{
            path:'./',           //输出路径
            filename:'index.js'  //输出文件
        },
        plugins: [
            new OpenBrowserPlugin({    //自动打开浏览器
                url: 'http://localhost:8080'
            })
        ],
        module:{
            loaders:[{
                test:/.jsx?$/,              //正则匹配 js 文件变化
                exclude:/node_modules/,   
                loader:'babel',
                query:{
                    presets:['es2015','react']   //将es6与react变成现代浏览器能看懂的语言
                }
            },{
                test:'/.(png|jpg|woff|woff2)$/',
                loader:'url-loader?limit=8192'     //自动将低于8192bit的图片变成base64
            },{
                test:/.json$/,
                loader:'json-loader'      //加载json文件
            }]
        }
    };
    module.exports = config;

    再看一下 package.json文件的内容

      ...
    "scripts": {
        "start": "webpack-dev-server"
      },
      ...
      "dependencies": {
        "babel-core": "^6.10.4",
        "babel-loader": "^6.2.4",
        "babel-preset-es2015": "^6.9.0",
        "babel-preset-react": "^6.11.1",
        "json-loader": "^0.5.4",
        "open-browser-webpack-plugin": "0.0.2",
        "react": "^15.2.0",
        "react-dom": "^15.2.0"
      }

    接下来看一下main.js 文件的内容

    import React from 'react';
    import ReactDOM from 'react-dom';
    import Slider from './App.jsx';     //引入APP.jsx
    
    ReactDOM.render(
        <Slider/>,
        document.getElementById('example')
    );

    最重要的内容是APP.jsx 接下来一起学习重头戏

    思路:

    0.将数据引入,通过使用webpack的 json.loader,将json 格式的值读取,方便后续拿到数据

    var imgData = require('./data/imgDatas.json');
    
    //将图片名信息转成图片URL路径信息
    imgData.forEach((item, index)=>{
        item.isRight = index % 2;    //根据奇偶判断 用于后面识别class="main-i_right"
        item.img = '/imgs/'+item.img;  //jsoan数据加上相对路径
    });

    1.拆分按钮 templateCtrl 和图片templateMain 组件

     return (
         <div className="slider">
           <div className="main">
              {templateMain}
           </div>
           <div className="ctrl">
               {templateCtrl}
           </div>
          </div>
    );

    2.设置getInitialState  current:0 这个是用于判断当前显示的值,将会与索引index相比较,相同则ture 添加 class="main-i_active"

    //ES5 的React
    getInitialState : function(){
            return{
                current : 0
            };
        },
    
    //ES6 的React
    constructor(){
            super();
            this.state = {
                current : 0
            };
        }

    3.根据图片数据foreach设置templateCtrl templateMain  的props数据,并初始化各自组件中间状态值isCenter为false

    let templateMain=[],templateCtrl=[];
            imgData.forEach((value , index)=>{
                var center = this.state.current == index; //这是核心,用于根据state.current 与 索引的值相比较 从而给每个组件的isCenter ture或false 加上对应的active
    
                templateMain.push(
                    <TemplateMainI
                        key={index}
                        {...value} //这里面有 img    isRight 
                        isCenter={center}
                    />
                );
                templateCtrl.push(
                    <TemplateCtrlI
                        key={index}
                        src={value.img}
                        isCenter={center}
                        arrange={this.rearrange.bind(this,index)} //通过点击触发rearrange,传递对应索引 设置state.current
                    />
                );
            });

    4.渲染templateCtrl templateMain组件

    class TemplateMainI extends React.Component{
        render () {
            const props = this.props,
                mainClassName = (props.isRight?'main-i main-i_right':'main-i')+
                    (props.isCenter?' main-i_active':'');
    
            return(
                <div className={mainClassName}>
                    <div className="caption">
                        <h2>{props.h1}</h2>
                        <h3>{props.h2}</h3>
                    </div>
                    <img src={props.img} alt=""/>
                </div>
            )
        }
    }
    class TemplateCtrlI extends React.Component{
        render() {
            const props = this.props;
            var ctrlClassName = 'ctrl-i'+ ( props.isCenter ?' ctrl-i_active':'');
    
            return(
                <a className={ctrlClassName} onClick={props.arrange}>
                    <img src={props.src} alt=""/>
                </a>
            )
        }
    }

    5.主方法:rearrange(index) 将选中值的state.current 设置为那个索引

    rearrange(index){
            this.setState({
                current : index
            });
        }

    6.为了让一开始渲染就有画面呈现,我们设置  componentDidMount 将第一个画面设置为最初始

    componentDidMount(){
            this.rearrange(0);
        }

    接下来对比es6下的React

    1、导入文件使用 import React from 'react'

    2、var TemplateMainI = React.createClass({}) 写法变成定义一个类继承React的组件  class TemplateMainI extends React.Component{}

    3、State  

    getInitialState : function(){
            return{
                imgsArrangeArr : []
            };
        },

    在构造器中继承父类

    es6语法
    constructor(){ super();
    this.state = { imgsArrangeArr : [] }; }

    4、function XXX(){}  变成 es6 方法的写法  XXX(){}

    5、onClick 传递到父组件之后,父组件的方法arrange 需要bind this     

    this.rearrange.bind(this,index)

    其中还有很多变化需要细细研究 可以参考这篇文章

    具体代码可以研究下我的github地址 Preview_silder,动手做一遍,收益良多。同时非常感谢楼下的博友帮我指出的错误。

    如果你已经学过了上面的内容,可以继续此项目的进阶,增加Redux整理数据 React+Redux 实现幻灯片

    转载请注明出处!!!

    by 邱XX:http://www.cnblogs.com/QRL909109/p/5683193.html

  • 相关阅读:
    Linux系统管理
    Linux命令—压缩及其他
    Linux命令—文件目录
    SQL基本函数
    35.app后端搜索入门
    Java-希尔排序
    Android 显示意图和隐式意图的差别
    做webapp 使用JS来检測游览器是什么类型,或android是什么版本
    用iframe在您的站点中增加findjar的功能
    HDU 4026 Unlock the Cell Phone( 状态压缩 )
  • 原文地址:https://www.cnblogs.com/QRL909109/p/5683193.html
Copyright © 2011-2022 走看看