• 使用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

  • 相关阅读:
    生日小助手源码运行的步骤
    关于生日小助手跨平台兼容性的临时解决方案
    生日小助手V3.0——跨平台的农历生日提醒软件
    生日小助手V3.1——跨平台多语言的农历生日提醒软件
    有关生日小助手的内容,请浏览生日小助手官方网站……
    生日小助手的详细规划——本博文随时更新,持续有效
    生日小助手V2.0发布了——可以正式投入使用!
    前端开发入门的几本推荐书籍
    多想一想,JS中函数声明和函数表达式的区别
    table固定宽度大小
  • 原文地址:https://www.cnblogs.com/QRL909109/p/5683193.html
Copyright © 2020-2023  润新知