零、前言
最近一直在總結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.搭建靜態頁面
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;
}
}
複製程式碼
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--生成若干的條目
輔助函式:隨機顏色:
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
<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.右欄的控制介面:
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}/>
複製程式碼
這樣靜態頁面和回撥都實現了,下面只要對回撥具體邏輯進行編寫就行了
三、回撥的具體邏輯
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.更多關於我
筆名 | 微信 | 愛好 | |
---|---|---|---|
張風捷特烈 | 1981462002 | zdl1994328 | 語言 |
我的github | 我的簡書 | 我的掘金 | 個人網站 |
3.宣告
1----本文由張風捷特烈原創,轉載請註明
2----歡迎廣大程式設計愛好者共同交流
3----個人能力有限,如有不正之處歡迎大家批評指證,必定虛心改正
4----看到這裡,我在此感謝你的喜歡與支援