首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React战记之玩转Flex布局(上篇--容器属性)

React战记之玩转Flex布局(上篇--容器属性)

作者头像
张风捷特烈
发布2018-12-25 15:15:18
9980
发布2018-12-25 15:15:18
举报
零、前言

最近一直在总结Android,前端这块感觉忘得也差不多了 Flex布局以前也听过,但没有详细学习过,趁机会用React玩转一下, 遇到一个新的知识怎么学,一大堆的参数让人发懵,我最喜欢的一句话:能应对变化的只有变化本身 用自己的能力让学习的对象非静态,就像与你交流的是一个活的人而非人偶 本文并非React基础教程,也非Flex布局讲解教程,只是做一个Flex布局演示器 源码见文尾捷文规范

不废话了,留图镇楼:

效果图


一、搭建React项目:
1.创建+scss配置

个人比较喜欢scss,最新的create-react-app的webpack已经对scss进行了配置 只需添加node-sass就行了

npm i create-react-app
npm i node-sass -D

2.搭建静态页面

静态页面.png


2.1:.Flex矩形div(默认长宽1000*300px)
.Flex {
  border: red 2px solid;
  margin-top: 20px;
  margin-left: 20px;
  width: 1000px;
  height: 300px;
  background-color: rgba(71,71,71,.6);
  display: flex;
  .title {
    border-radius: 10px;
    font-size: 30px;
    text-align: center;
  }
}

Flex.png


2.2--数据准备:
export class AttrData {
    static getAttrData() {

        let justifyContent = {
            index: 0,
            data: ["normal", "flex-start", "flex-end", "center", "space-between", "space-around"]
        };
        let flexDirection = {
            index: 0,
            data: ["row", "row-reverse", "column", "column-reverse"]
        };
        let flexWrap = {
            index: 0,
            data: ["nowrap", "wrap", "wrap-reverse"]
        };
        let alignItems = {
            index: 0,
            data: ["normal", "stretch", "flex-start", "flex-end", "center", "baseline"]
        };
        let alignContent = {
            index: 0,
            data: ["normal", "stretch", "flex-start", "flex-end", "center", "space-between", "space-around"]
        };

        return {justifyContent, flexDirection, flexWrap, alignItems, alignContent};
    }

    /**
     * 设置属性
     * @param attr
     * @returns {*}
     */
    static getAttrLooped(attr) {
        return attr.data[attr.index % attr.data.length];
    }

    /**
     * 获取属性
     * @param attr
     * @returns {*}
     */
    static getAttr(attr) {
        return attr.data[attr.index];
    }
}
2.3--数据填充
//获取数据和函数
const attrData = Data.getAttrData();
const getAttrLooped = Data.getAttrLooped;
const getAttr = Data.getAttr;

let justifyContent = attrData.justifyContent;
let flexDirection = attrData.flexDirection;
let flexWrap = attrData.flexWrap;
let alignItems = attrData.alignItems;
let alignContent = attrData.alignContent;

//对div进行数据填充
<div className="Flex" style={{
    width: this.state.ctrl[1].data + "px",
    height: this.state.ctrl[2].data + "px",
    flexDirection: getAttrLooped(flexDirection),
    flexWrap: getAttrLooped(flexWrap),
    justifyContent: getAttrLooped(justifyContent),
    alignItems: getAttrLooped(alignItems),
    alignContent: getAttrLooped(alignContent)
}}>
    {this.formItem()}
</div>
2.5--生成若干的条目

加条目.png

辅助函数:随机颜色:Logic.randomRGB

/**
 * 随机颜色
 * @param a 透明度--默认为1
 * @returns {string}
 */
static randomRGB(a = 1) {
    return `rgba(${this.rangeInt(0, 255)},${this.rangeInt(0, 255)},${this.rangeInt(0, 255)},${a})`
}

根据数组动态生成随机颜色的条目:Flex.formItem

formItem() {
    let color = [];
    for (let i = 0; i < this.state.ctrl[0].data; i++) {
        color.push(Logic.randomRGB(.8))
    }
    return (
        color.map((item, index) => {
            return (
                <div className={"title"} style={{backgroundColor: item}} key={index}>
                    Toly{index}
                </div>
            );
        })
    )
}

3.底部栏的组件:ListInfo.js

底部+点击回调.png

<ListInfo data={this.state.flexObj}
          onItemClick={this.onItemClick.bind(this)}/>

3.1:数据的获取:flexObj
/**
 * 底部监听--属性变化
 */
notifyAttrChanged() {
    this.setState({
        flexObj: {
            "flex-direction": getAttr(flexDirection),//元素排列方向
            "flex-wrap": getAttr(flexWrap),//换行
            "justify-content": getAttr(justifyContent),//水平对齐方式
            "align-items": getAttr(alignItems),//垂直对齐方式
            "align-content": getAttr(alignContent),//多行垂直对齐方式,
        }
    });
}

3.2:数据的显示:ListInfo.js
import React, {Component} from 'react';
import './ListInfo.scss'

class ListInfo extends Component {
    render() {
        return (
            <div className="ListInfo" >
                {this.formList(this.props.data)}
            </div>
        )
    }

    formList(data) {//对象转化数组
        let datas = [];
        for (let key in data) {
            datas.push({
                    name: key,
                    data: data[key]
                }
            );
        }

        return (
            <div id="list-container">
                {datas.map((item, index) => {
                    return (//此处点击回调onItemClick,捕获索引
                        <div key={index} className="card" onClick={() => {
                            this.props.onItemClick && this.props.onItemClick(index);
                        }}>
                            {item.name}:<br/>
                            {item.data}<br/>
                        </div>
                    )
                })}
            </div>
        )
    }
}

3.3:样式:ListInfo.scss
#list-container {
  display: flex;

  .card{
    background-color: #26A5F8;
    cursor: pointer;
    margin-top: 20px;
    margin-left: 30px;
    padding: 10px;
    font-weight: bold;
    font-size: 24px;
    border-radius: 10px;
    box-shadow: #61dafb 2px 2px 10px 2px;
  }
}

4.右栏的控制界面:

右侧控制.png

4.1:state数据:Flex.js
this.state = {
    flexObj: '',
    ctrl: [
        {
            data: 10,
            info: "条目数量",
            fun: (input) => {
                this.notifyInputChanged(0, input)
            }
        },
        {
            data: 1000,
            info: "容器宽度",
            fun: (input) => {
                this.notifyInputChanged(1, input)
            }
        },
        {
            data: 300,
            info: "容器高度",
            fun: (input) => {
                this.notifyInputChanged(2, input)
            }
        },
        {
            data: "auto",
            info: "条目宽度",
            fun: (input) => {
                this.notifyInputChanged(3, input)
            }
        },
        {
            data: "auto",
            info: "条目高度",
            fun: (input) => {
                this.notifyInputChanged(4, input)
            }
        }
    ]
}

4.2:接收数据,渲染界面+回调CtrlBox.js
import React, {Component} from 'react';
import './CtrlBox.scss'

class CtrlBox extends Component {

    render() {
        return (
            <div className="right-ctrl">
                {this.createItem(this.props.ctrl)}
            </div>
        )
    }

    createItem(ctrl) {
        return (
            ctrl.map((item, index) => {
                return (
                    <div className={"container"} key={index}>
                        <label>{this.props.ctrl[index].info}:</label>
                        <input
                            onChange={
                                (v) => {
                                    this.bindCallback(index, v);
                                }}
                            defaultValue={this.props.ctrl[index].data}/>
                        <label>px</label>
                    </div>
                );
            })
        )
    }

    /**
     * 绑定回调事件
     * @param index
     * @param v
     */
    bindCallback(index, v) {
        switch (index) {
            case 0:
                this.props.onCountChanged(v.target.value);
                break;
            case 1:
                this.props.onBoxWidthChanged(v.target.value);
                break;
            case 2:
                this.props.onBoxHeightChanged(v.target.value);
                break;
            case 3:
                this.props.onItemWidthChanged(v.target.value);
                break;
            case 4:
                this.props.onItemHeightChanged(v.target.value);
                break;
            default:
                break;
        }
    }
}

export default CtrlBox;

4.3、回调函数与使用:Flex.js
<CtrlBox
    ctrl={this.state.ctrl}
    onCountChanged={this.state.ctrl[0].fun}
    onBoxWidthChanged={this.state.ctrl[1].fun}
    onBoxHeightChanged={this.state.ctrl[2].fun}
    onItemWidthChanged={this.state.ctrl[3].fun}
    onItemHeightChanged={this.state.ctrl[4].fun}/>

静态界面.png

这样静态页面和回调都实现了,下面只要对回调具体逻辑进行编写就行了


三、回调的具体逻辑

1.点击下方条目时,动态改变数据
/**
 * 点击下方条目
 * @param index
 */
onItemClick(index) {
    switch (index) {
        case 0:
            flexDirection.index++;
            break;
        case 1:
            flexWrap.index++;
            break;
        case 2:
            justifyContent.index++;
            break;
        case 3:
            alignItems.index++;
            break;
        case 4:
            alignContent.index++;
            break;
        default:
            break;
    }
    this.notifyChanged();
}

2:输入数据变动监听
/**
 * 输入监听--数据变化
 * @param index
 * @param input
 */
notifyInputChanged(index, input) {
    let ctrl = this.state.ctrl;
    ctrl[index].data = input;
    this.setState({
        ctrl
    });
}

看似功能挺复杂,其实也就这点代码,重点在于数据的把握与对象的封装 我并非一开始就能把数据统筹成这样,也是遇到了,看能合并,就合并一下,零散的属性看着烦心 这也全靠Android(或java)让我对对象认识深刻,所以什么事就是有联系的,思想有了,一切好办


后记:捷文规范
1.本文成长记录及勘误表

项目源码

日期

备注

V0.1--github

2018-12-9

React战记之玩转Flex布局(上篇--容器属性)

2.更多关于我

笔名

QQ

微信

爱好

张风捷特烈

1981462002

zdl1994328

语言

我的github

我的简书

我的掘金

个人网站

3.声明

1----本文由张风捷特烈原创,转载请注明 2----欢迎广大编程爱好者共同交流 3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正 4----看到这里,我在此感谢你的喜欢与支持

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.12.09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 零、前言
    • 不废话了,留图镇楼:
    • 一、搭建React项目:
      • 1.创建+scss配置
        • 2.搭建静态页面
          • 2.1:.Flex矩形div(默认长宽1000*300px)
          • 2.2--数据准备:
          • 2.3--数据填充
          • 2.5--生成若干的条目
        • 3.底部栏的组件:ListInfo.js
          • 3.1:数据的获取:flexObj:
          • 3.2:数据的显示:ListInfo.js
          • 3.3:样式:ListInfo.scss
        • 4.右栏的控制界面:
          • 4.1:state数据:Flex.js
          • 4.2:接收数据,渲染界面+回调CtrlBox.js
          • 4.3、回调函数与使用:Flex.js
      • 三、回调的具体逻辑
        • 1.点击下方条目时,动态改变数据
          • 2:输入数据变动监听
          • 后记:捷文规范
            • 1.本文成长记录及勘误表
              • 2.更多关于我
                • 3.声明
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档