高端科技产品网站建设,wordpress函数大全,wordpress速度快了很多,自己建网站的优势一、前言
手写Table组件这个文章我一直都想写#xff0c;今天终于得空来写它了。小编认为Table组件是组件库里较为复杂的一个组件#xff0c;因为它的扩展性非常强#xff0c;并且它的基础样式如何去写都非常考究#xff0c;那么今天我就带大家来实现一个基础…一、前言
手写Table组件这个文章我一直都想写今天终于得空来写它了。小编认为Table组件是组件库里较为复杂的一个组件因为它的扩展性非常强并且它的基础样式如何去写都非常考究那么今天我就带大家来实现一个基础功能的table组件废话不多bb进入正题吧。
二、实现哪些功能
最基础的table布局固定头固定列
三、实现的效果 以及组件的使用方式期望是这样
const column [{ name: 序号, key: order, width: 100px, isFixed: true },{ name: 第二列, key: col2, width: 200px },{ name: 第三列, key: col3, width: 300px },{ name: 第四列, key: col4, width: 200px },{ name: 第五列, key: col5, width: 500px },{ name: 第六列, key: col6, width: 200px },
];
const data [{ order: 1, col2: 1-2, col3: 1-3, col4: 1-4, col5: 1-5, col6: 1-6 },{ order: 2, col2: 2-2, col3: 2-3, col4: 2-4, col5: 2-5, col6: 2-6 },{ order: 3, col2: 3-2, col3: 3-3, col4: 3-4, col5: 3-5, col6: 3-6 },{ order: 4, col2: 4-2, col3: 4-3, col4: 4-4, col5: 4-5, col6: 4-6 },{ order: 5, col2: 5-2, col3: 5-3, col4: 5-4, col5: 5-5, col6: 5-6 }
];
CustomTablecolumn { column } data { data } rowHeight { 100px } / 四、动手实现
4.1、table组件的尺寸
4.1.1、如何定义table组件的宽
对于table组件来说定义宽度有2种方式一种是固定宽度布局另一种是自由宽度布局。我们可以通过table-layout属性在这2种方式中做出选择。
4.1.1.1、“固定宽度布局” 就是显示的定义table标签的宽度(即table-layout: fixed)那么此时 table 的宽度 与 各列 [td | th] 的宽度的关系如下 table真实的width Math.max(table.style.width, 各列宽度之和)如果 table.style.width 各列宽度之和那么二者之差再除以列数得到的结果将增加到各列上。 纸上得来终觉浅我们来跑下代码加深一下上述节论的记忆(以下均是react环境下的代码)
table {table-layout: fixed;border-collapse: collapse;border-spacing: 0px;width: 200px;
} div className yon-table-boxtablecolgroupcol style{{ width: 100px }}col style{{ width: 100px }}col style{{ width: 100px }}colgrouptheadth列1/thth列2/thth列3/th/thead/table
/div 此时效果如下 此时我们再稍微改动下样式css如下
table {table-layout: fixed;width: 500px;border-collapse: collspse;border-spacing: 0px;
} 效果如下 此时我们发现上述结论是对的。
4.1.1.2、“自由宽度布局” 顾名思义更容易实现这个等式 “table.style.width 各列宽度之和 边框 间距”。通过设置 table-layout: auto 来触发。 我们来跑下代码试一下
table {table-layout: auto;border-collapse: collapse;border-spacing: 0px;width: auto;
} div className table-boxtablecolgroupcol style{{ width: 100px }}col style{{ width: 100px }}col style{{ width: 100px }}/colgrouptheadth列1/thth列2/thth列3/th/thead/table
/div 此时我们来看下效果 4.1.1.3、table宽度的最终选择
经过上面2种布局的分析我们决定选用自由宽度布局的方式定义table的宽度此时咱们的CustomTable组件的代码如下 .yon-table-box {width: 100px;height: 100px;overflow: scroll;}table {table-layout: auto;table-collapse: collapse;table-spacing: 0px;width: auto;}th {background: #f4f4f4;} import React from react;class CustomTable extends React.Component {constructor(props){super(props)}render (){const { column } this.props;return div className yon-table-boxdiv className righttablecolgroup{column.map(colItem {return col style{{ colItem.width }}})}/colgrouptheadtr{column.map(colItem {return th{ colItem.name }/th})}/tr/thead/table/div/div}} Table的使用: import React from react;const column [{ name: 列1, key: col1, width: 100px },{ name: 列2, key: col2, width: 200px },{ name: 列3, key: col3, width: 300px },];CustomTable column { column } / 4.1.2、如何定义table组件的高
定义table组件的行高度这个就比较简单了我们只需要保证 table.style.height ‘auto’, 即可实现自定义行高CustomTable组件的代码如下 .yon-table-box {width: 100px;height: 100px;overflow: scroll;}table {table-layout: auto;table-collapse: collapse;table-spacing: 0px;width: auto;// 新增代码height: auto;}th {background: #f4f4f4;}// 新增代码td {background: #fff;border-bottom: 1px solid rgb(208, 208, 208);} import React from react;class CustomTable extends React.Component {constructor(props){super(props)}render (){const { column, data, rowHeight } this.props;return div className yon-table-boxdiv className righttablecolgroup{column.map(colItem {return col style{{ colItem.width }}})}/colgrouptheadtr{column.map(colItem {return th{ colItem.name }/th})}/tr/theadtbody{// 新增代码data.map(dataItem {return tr{column.map(colItem {return td style{{ height: rowHeight }}{dataItem[colItem.key]}/td})}/tr})}/tbody/table/div/div}} 好啦此时咱们的第一个功能到这就算实现啦如果你是一步一步跟下来的那么此时的效果应该是这样的 4.2、固定列
我们先来看一下下面的图 首先根据目前实现的效果来看我们可以得出以下信息
目前dom上就只有一个table意味着 表头、表体是连着的符合正常文档流所有的特点。红色框是我们想要固定的列。
好此时我们来想一下能够做到固定列无非是2个div互不干扰呗的方法有哪些
4.2.1、方式一
把一个table分为左右2个table并保证只有右侧的table局部滚动干掉父div的scroll。
4.2.2、方式二
依旧是一个table分为左右2个table只是在不改变现在滚动的情况下给左侧的table新增一个sticky的粘性定位即可。
4.2.3、方式三
利用js监听scroll事件在滚动的时候利用transform属性动态的设置translateX来达到固定列的效果
4.2.3、固定列的最终选择 这里我们选择 方式二。理由非常简单改动量非常少的情况就可以实现其他的2种情况的改动都挺大但是也可以实现下面我会把其他的2种方式的伪代码写出来供大家参考。 方式一。其实这种方式更适合固定宽度布局的table因为这种table的width是非常容易拿到的你只需要保证列数过多的时候出现滚动条就可以也仅仅是一行样式的问题,伪代码如下 import React from react;export default class App extends React.Component {constructor(props){super(props)}render (){return div style{{ display: flex }}!-- 左侧固定列 --div className lefttable/table/div!-- 右侧自由列 --div className right style{{ overflow: scroll }}table/table/div/div}} 方式三。这种利用js的方式是最看重代码结构的而且还会使你的代码变得非常臃肿不利于拆分它比较适用于下面的写法: import React from react;// 大家看到这样的写法其实可能感觉不到什么但是如果这样写的话table组件的抽取将会异常困难。class App extends React.Component {constructor(props){super(props)this.leftTableRef React.createRef();this.scrollTableBox React.createRef();}scrollTable () {// 保持左侧固定不动this.leftTableRef.current.style.transform translateX(-${this.scrollTableBox.current.scrollLeft};}render (){return div ref { this.scrollTableBox } style{{ display: flex, overflow: scroll }} onScroll { () this.scrollTable() }!-- 左侧固定列table --table ref{ this.leftTableRef }/table!-- 右侧自由列table --table/table/div}} 4.2.4、固定列的最终代码 .yon-table-box {width: 100px;height: 100px;overflow: scroll;}table {table-layout: auto;table-collapse: collapse;table-spacing: 0px;width: auto;// 新增代码height: auto;} th { background: #f4f4f4;} // 新增代码td {background: #fff;border-bottom: 1px solid rgb(208, 208, 208);}// 新增代码.left {position: sticky;left: 0px;} import React from react;class CustomTable extends React.Component {constructor(props){super(props)this.state {// 固定列集合fixedColumnArr : [];// 自由列集合notFixedColumnArr: [];}}componentDidMount(){const { column } this.props;this.setState(state {return {// column配置项中isFixed用于标识是否是固定列fixedColumnArr : column.filter(item item.isFixed),notFixedColumnArr: column.filter(item !item.isFixed)}})}render (){const { data, column, rowHeight } this.props;const { fixedColumnArr, notFixedColumnArr } this.state;return div className yon-table-box{ fixedColumnArr.length 0 div className left table colgroup { fixedColumnArr.map(item { return col style{{ minWidth: item.width, width: item.width }} }) } /colgroup thead tr { fixedColumnArr.map(item { return th{item.name}/th }) } /tr /thead tbody { data.map(dataItem { return tr { fixedColumnArr.map(colItem { return td{dataItem[colItem.key]}/td }) } /tr }) } /tbody /table /div}div className right!-- 跟left代码一样只需要把 fixedColumnArr 换成 notFixedColumnArr 即可 --/div/div}} 4.3、固定头
固定头的实现思路 其实和 固定列的思路是一样的这里就不具体分析了夜也深了哈哈哈这里我就偷点懒给伪代码了: import React from react;class CustomTable extends React.Component {constructor(props){super(props)this.state {// 固定列集合fixedColumnArr : [];// 自由列集合notFixedColumnArr: [];}}render (){const { data, column, rowHeight } this.props;return div className yon-table-box// 整张表的头部整个头部是需要sticky的div className topdiv className left/divdiv className right/div/div// 整张表的body左侧需要固定的body是需要sticky的div className bottomdiv className left/divdiv className right/div/div/div}} 五、最后
好啦table组件这次就分享到这里了文章里有讲的不对的地方欢迎大家指正如果大家对table组件的实现有什么好的想法也欢迎评论留言那么886~~~
最后
为大家准备了一个前端资料包。包含54本2.57G的前端相关电子书《前端面试宝典附答案和解析》难点、重点知识视频教程全套。 有需要的小伙伴可以点击下方卡片领取无偿分享