自定义列数
,后端数据返回的就是数组,你看你前端咋弄啊自定义多列
嘛简单。思考 ing: 我有一个数组 list
,输入对应的列数 col
,就可以展示对应的列数,大概的 demo
我都写好了在下面const cols:number = 3;
const list:Array<any> = [1,2,3,4,5,6,7]
<MultiBox columns={cols} list={list}/>
// show list
1 | 2 | 3
4 | 5 | 6
7 | |
column-count
css 属性,先用字符串试试, 在实际使用数组的时候发现不好使;column-count
的定义 column-count CSS属性,描述元素的列数。
column-count: 3;
column-count: auto;
Block containers except table wrapper boxes
> 定义:<number> 是个严格的正数 <integer> ,用来描述元素内容被划分的理想列数. 假如 column-width (en-US)也被设置为非零值, 此参数仅表示所允许的 "最大列数"
• 注意上面的 最大列数 这里就是坑了,你指定的 number 并不一定是现在的列数,而是最大列数
import React from "react";
type IMultiBoxProps = {
cols?: number;
list: string | Array<any>;
};
const MultiBox = (props: IMultiBoxProps) => {
const { cols = 1, list } = props;
return (
<div
style={{
columnCount: cols
}}
>
{Array.isArray(list) ? list.join("") : list}
</div>
);
};
export default function App() {
const defaultMultiBox1Props = {
cols: 3,
list:
"当我年轻的时候,我梦想改变这个世界;当我成熟以后,我发现我不能够改变这个世界,我将目光缩短了些,决定只改变我"
};
const defaultMultiBox2Props = {
cols: 3,
list: [1, 2, 3, 4, 5, 6, 7, 8, 9]
};
return (
<div className="App">
<h1>Test MultiBox</h1>
<MultiBox {...defaultMultiBox1Props} />
<MultiBox {...defaultMultiBox2Props} />
</div>
);
}
const MultiBox = (props: IMultiBoxProps) => {
const { cols = 1, list } = props;
return (
<div>
<ul style={{
columnCount: cols
}}>
{list.map(val => <li>{val}</li>)}
</ul>
</div>
);
};
list = [1, 2, 3, 4, 5, 6, 7, 8, 9];
<MultiBox cols={3} list={list} />
// 3 列没问题
| 1 | 4 | 7 |
| 2 | 5 | 8 |
| 3 | 6 | 9 |
<MultiBox cols={6} list={list} />
// 只有 5 列 ?
| 1 | 3 | 5 | 7 | 9
| 2 | 4 | 6 | 8 |
这里就要提到上面的此参数仅表示所允许的 "最大列数"这个坑了
column-count
的计算方法, 首先计算每列可以承载最大的 items 数, 我们来试着模拟计算一下const cols = 6;
const list = [1,2,3,4,5,6,7,8,9];
const result = [];
const countSize = Math.ceil(list.length / cols); // 2
for (let i = 0, len = list.length; i < len; i += countSize) {
result.push(list.slice(i, i + countSize));
}
// [1,2]
// [3,4]
// [5,6]
// [7,8]
// [9]
cols
的数量。二维数组
,我们可以先搞一个 table[cols]
的数组,然后按照每列插值保证列数优先,就安全了,能保证定义多少列就展示多少列。const cols = 6;
const list = [1,2,3,4,5,6,7,8,9];
function chunker(cols, lists){
const table = new Array(cols);
for (let i = 0; i < table.length; i++) {
table[i] = new Array();
}
while (lists.length > 0) {
// insert one rows
for (let col = 0; col < table.length; col++) {
table[col].push(lists.shift());
}
}
return table.filter(Boolean);
}
chunker(cols, list)
// [1,7]
// [2,8]
// [3,9]
// [4]
// [5]
// [6]
// css
.flex-direction-column{
flex-direction: column;
}
.flex {
display: flex;
}
// tsx
const MultiBox = (props: IMultiBoxProps) => {
const { cols = 1, list } = props;
const chunks = chunker(cols, list);
return (
<div className="flex">
{chunks.map(col =>
<div className="flex-direction-column">
{col.map(item => item)}
</div>
)}
</div>
);
};
.gird-layout {
display: grid;
grid-template-columns: repeat(3, 33.33%);
// 三列布局
}
const MultiBox = (props: IMultiBoxProps) => {
const { cols = 1, list } = props;
return (
<div
style={{
display: 'gird',
gridTemplateColumns: repeat(cols, 1/cols);
}}
>
{list.map( item => <div>{item}</div>)}
</div>
);
};
gridTemplateColumns: repeat(cols, 1/cols);
repeat 不能直接使用, gird 方法是找到了,有什么优雅的方法解决这个问题啦?