HzHeader.jsx源码
/root/workspace/actionview/av-github-source-code/actionview-fe/app/components/gantt/HzHeader.jsx
import React, { PropTypes, Component } from 'react';
import _ from 'lodash';
export default class HzHeader extends Component {
constructor(props) {
super(props);
}
static propTypes = {
cellWidth: PropTypes.number.isRequired,
dates: PropTypes.object.isRequired,
today: PropTypes.string.isRequired
}
//shouldComponentUpdate(newProps, newState) {
// if (newProps.cellWidth != this.props.cellWidth && !_.isEqual(_.keys(newProps.dates), _.keys(this.props.dates))) {
// return true;
// }
// return false;
//}
render() {
const {
cellWidth,
dates,
today=''
} = this.props;
const w = _.flatten(_.values(dates)).length * cellWidth + 'px';
return (
<div className='ganttview-hzheader'>
<div className='ganttview-hzheader-months' style={ { width: w } }>
{ _.map(dates, (v, key) =>
<div className='ganttview-hzheader-month' key={ key } style={ { width: v.length * cellWidth + 'px' } }>
{ key }
</div> ) }
</div>
<div className='ganttview-hzheader-days' style={ { width: w } }>
{ _.map(_.flatten(_.values(dates)), (v, key) =>
<div className={ 'ganttview-hzheader-day ' + (v.date == today ? 'ganttview-today' : (v.notWorking === 1 ? 'ganttview-weekend' : '')) } style={ { width: cellWidth + 'px' } } key={ key }>
{ v.day }
</div> ) }
</div>
</div>);
}
}
源码解读
这段代码定义了一个名为 HzHeader
的 React 组件,用于渲染甘特图中的水平头部(Horizontal Header)。这个头部包含了月份和每天的标签,用于显示甘特图的时间范围。下面是对这段代码的详细解释:
导入模块
import React, { PropTypes, Component } from 'react';
import _ from 'lodash';
-
React
:React 的核心库。 -
PropTypes
:用于定义组件的 prop 类型检查。 -
lodash
:一个实用工具库,提供了很多常用的函数,如_.flatten
和_.isEqual
。
定义组件类
export default class HzHeader extends Component {
constructor(props) {
super(props);
}
-
HzHeader
类继承自Component
,表示这是一个 React 组件。 -
constructor
构造函数初始化组件,并调用父类构造函数super(props)
来初始化父类属性。
定义 prop 类型
static propTypes = {
cellWidth: PropTypes.number.isRequired,
dates: PropTypes.object.isRequired,
today: PropTypes.string.isRequired
}
propTypes
是一个静态属性,用于定义组件接受的 prop 类型。
-
cellWidth
:每个单元格的宽度。 -
dates
:一个对象,其键为月份,值为该月每一天的信息。 -
today
:今天的日期字符串。
shouldComponentUpdate 方法(注释掉)
//shouldComponentUpdate(newProps, newState) {
// if (newProps.cellWidth != this.props.cellWidth && !_.isEqual(_.keys(newProps.dates), _.keys(this.props.dates))) {
// return true;
// }
// return false;
//}
- 这是一个生命周期方法,用于判断组件是否需要重新渲染。
- 如果
cellWidth
发生变化,或者dates
对象的键发生变化,则返回true
表示需要更新。 - 如果没有变化,则返回
false
表示不需要更新。 - 注意:此方法已被注释掉,意味着默认情况下组件将遵循 React 的默认更新策略。
渲染方法
render() {
const {
cellWidth,
dates,
today=''
} = this.props;
const w = _.flatten(_.values(dates)).length * cellWidth + 'px';
return (
<div className='ganttview-hzheader'>
<div className='ganttview-hzheader-months' style={ { width: w } }>
{ _.map(dates, (v, key) =>
<div className='ganttview-hzheader-month' key={ key } style={ { width: v.length * cellWidth + 'px' } }>
{ key }
</div> ) }
</div>
<div className='ganttview-hzheader-days' style={ { width: w } }>
{ _.map(_.flatten(_.values(dates)), (v, key) =>
<div className={ 'ganttview-hzheader-day ' + (v.date == today ? 'ganttview-today' : (v.notWorking === 1 ? 'ganttview-weekend' : '')) } style={ { width: cellWidth + 'px' } } key={ key }>
{ v.day }
</div> ) }
</div>
</div>);
}
}
render
方法返回组件的 JSX 结构。
- 解构赋值
const { ... } = this.props
来提取传入的 props。 - 计算总宽度
w
:所有日期的单元格宽度之和。 - 渲染一个
<div>
容器,作为水平头部的基础。 - 渲染月份标签:
- 使用
_.map
循环遍历dates
对象的键值对。 - 每个月份标签的宽度等于该月所有日期的单元格宽度之和。
- 每个月份标签的类名为
ganttview-hzheader-month
。
- 渲染每天的标签:
- 使用
_.flatten(_.values(dates))
获取所有日期信息的扁平化数组。 - 使用
_.map
循环遍历每个日期信息。 - 每个日期标签的宽度为
cellWidth
。 - 根据当前日期是否为今天或是否为非工作日,调整类名。
- 每个日期标签的类名为
ganttview-hzheader-day
,并根据条件添加额外的类名。
总结
这个 HzHeader
组件负责渲染甘特图中的水平头部,包含每个月份的标签和每天的标签。组件根据传入的 props
动态计算每个标签的宽度,并根据当前日期和工作日状态调整类名。通过这种方式,组件能够灵活地适应不同的数据和布局需求,为用户提供清晰的时间范围视图。