定制化开发——时间轴组件

2023-11-10

一、需求

1、开发一个展示轨迹数据用的时间轴组件;
2、后端传入是一个 list,数据格式如下:

const dataRalation = [
	  {
	    entityID : "111",	// 主体id
	    accompanyID : "222",		// 伴随id
	    entityTime : "2019-08-05 22:26:34",	时间
	    accompanyTime : "2019-08-05 22:33:31",		// 伴随时间
	    entitySpace : "未知之地" ,		// 地点
	    accompanySpace : "未知之地" ,		// 伴随地点
	    entiyImg : "no_photo.png" ,		// 图片
	    accompanyImg : "no_photo.png" ,		// 伴随图片
	  },
	  ......
  ]

3、点击日期,其对应的下列数据可以收起
成果如下图:
在这里插入图片描述

&
在这里插入图片描述

二、思路

1、根据时间将传入的 list 数据转化为map。
2、提取日期作为map的键,剩下数据以数组的形式作为map键值对的值存储。
3、遍历map,根据map的数据来生成组件

三、代码

3.1、第一版代码

这是我当时写的第一版代码,其中有个bug。就是测试的时候发现一点击日期所有的展示数据都收起来了。导致的原因是控制展示的 displaytype是遍历生成的。故,组件中的的this.state.displaytype,指代了所有小组件的displaytype。当触发clickTitle方法时,所有的displaytype全部改变,没有实现第三点需求。

import * as React from 'react';
import {format} from 'date-fns';
import PerfectScrollbar from 'perfect-scrollbar';
import {Text} from '../../common/text';
import { IconFont } from '../../common/iconFont';

export interface IProps{
  // 关系对象数据
  data : any,
  // 左边加载的图片
  leftImg : string,
  // 右边加载的图片
  rightImg : string,
  // 颜色数组
  color : string[],
  // 主体对象类型
  objectType : string,
  // 关联对象类型
  relationType : string
}

// IListType[]
export interface IListType {
  objectaddress : string
  objectId : string
  objectTime : string
  unionaddress : string
  unionId : string
  unionTime : string
  entiyImg : string
  accompanyImg : string
}

export class TimeShaft extends React.PureComponent<IProps,any>{

  private dom: React.RefObject<HTMLDivElement> ;
  private scroller: PerfectScrollbar | undefined ;

  constructor(props:IProps){
    super(props);
    this.dom = React.createRef();
    this.state = {
      displayType : 'flex' ,
      objectType : this.props.objectType ,
      relationType : this.props.relationType
    }
  }

  public componentWillReceiveProps(nextProps:IProps){

    this.setState({
      objectType : nextProps.objectType,
      relationType: nextProps.relationType,
    });
    
  }

  // 组件渲染之后设置滚动条样式
  public componentDidMount() {
    const wrapper = this.dom.current;
    if (wrapper) {
      this.scroller = new PerfectScrollbar(wrapper, {
          wheelPropagation: false,
          wheelSpeed: 2,
      });
      this.updateScroller();
    }
  }
  // 组件更新后设置滚动条样式
  public componentDidUpdate() {
    this.updateScroller();
  }
  public updateScroller() {
    this.scroller!.update();
  }

  public render() {

    const html : any = [] ;
    
    const {displayType,objectType,relationType} = this.state;
    const {data,leftImg,rightImg,color} = this.props;
    // 定义一个map对象
    const map : Map<string,Array<[]>> = new Map<string,Array<[]>>();
    // 将data组装成map
    data.forEach((item:any, i:number) => {
      // 取时间的年月日 dateTitle,作为map的键
      const dateTitle = format(item.entityTime, 'YYYY-MM-DD');
      // 如果map的键值对中没有 dateTitle,则set一个并创建一个空数组存储值
      if(!map.has(dateTitle)){
        map.set(dateTitle,[]);
      }
      // 如果map中已有该键值对,往数组中push遍历的对象item
      const list = map.get(dateTitle);
      if(list){
        list.push(item);
      }
    });

    // 先生成htmlbody
    map.forEach((list, value) => {
      const datalist : IListType[] = []
      // htmlbody要写在foreach循环里面,如果写全局变量最后会把全部结果push进去
      const htmlbody : any = [] ;

      list.forEach((item:any, num :number) => {
        datalist.push({
          objectaddress : item.entitySpace,
          objectId : item.entityID ,
          objectTime : item.entityTime,
          unionaddress : item.accompanySpace,
          unionId : item.accompanyID,
          unionTime : item.accompanyTime,

          entiyImg : item.entiyImg ,
          accompanyImg : item.accompanyImg ,
        })

        htmlbody.push(
          <div style={{display:displayType, width:'100%'}}>
            {/* 左 */}
            <div className="shaft-htmlbody-main" style={{ justifyContent:'flex-end'}}>
              <div className="shaft-htmlbody-dif" style={{ marginRight:'10px' }}>
                <div className="shaft-htmlbody-border" style={{ border:'1px solid' + color[0] }}>

                  <div className="shaft-htmlbody-smallTitle" style={{backgroundColor:color[0]}}>
                    <img className="shaft-htmlbody-img" src={leftImg} alt=""/>
                    <div className="shaft-htmlbody-font">
                      { objectType  === '01' 
                        ? <Text widths="120px" data={datalist[num].objectId.slice(0,7)}/> 
                        : <Text widths="120px" data={datalist[num].objectId}/> }
                    </div>
                  </div>

                  <div className="shaft-htmlbody-dataImg">
                    <img style={{ width:'100%' }} src={datalist[num].entiyImg}/>
                  </div>

                  <div className="shaft-htmlbody-time">
                    <div style={{width:'40%'}}>过卡时间:</div>
                    <Text widths="60%" data={format(datalist[num].objectTime, 'HH:mm:ss')}/>
                  </div>

                  <div className="shaft-htmlbody-space">
                    <div style={{width:"40%"}}>卡口地点:</div>
                    <Text widths="60%" data={datalist[num].objectaddress}/>
                  </div>

                </div>
              </div>
            </div>
            
            {/* 中间icon */}
            <div style={{width: 2, display:'flex', flexDirection:'column'}}>
              <div style={{width: 2, backgroundColor: '#e6e6e6',height:30}}>{}</div>
              <div style={{width: 2, height:32}}>
                <IconFont extraCommonProps={ {style:{fontSize:30,color:'#b3b3b3',marginLeft:-15}} } type="iconshijian2" />
              </div>
              <div style={{width: 2, backgroundColor: '#e6e6e6', flex:'1'}}>{}</div>
            </div>

            {/* 右 */}
            <div className="shaft-htmlbody-main" style={{ justifyContent:'flex-start'}}>
              <div className="shaft-htmlbody-dif" style={{marginLeft:'10px'}}>
                <div className="shaft-htmlbody-border" style={{ border:'1px solid'+color[1] }}>

                  <div className="shaft-htmlbody-smallTitle" style={{ backgroundColor:color[1] }}>
                    <img className="shaft-htmlbody-img" src={rightImg} alt=""/>
                    <div className="shaft-htmlbody-font">
                      { relationType  === '01' 
                        ? <Text widths="120px" data={datalist[num].unionId.slice(0,7)}/> 
                        : <Text widths="120px" data={datalist[num].unionId}/> }
                    </div>
                  </div>

                  <div className="shaft-htmlbody-dataImg">
                    <img style={{ width:'100%' }} src={datalist[num].accompanyImg}/>
                  </div>

                  <div className="shaft-htmlbody-time">
                    <div style={{width:"40%"}}>过卡时间:</div>
                    <Text widths="60%" data={format(datalist[num].unionTime, 'HH:mm:ss')}/>
                  </div>

                  <div className="shaft-htmlbody-space">
                    <div style={{width:'40%'}}>卡口地点:</div>
                    <Text widths="60%" data={datalist[num].unionaddress}/>
                  </div>

                </div>
              </div>
            </div>

          </div>
        )
      })
      // 按value值循环生成htmlbody后,再生成html模块
      html.push(
        <div style={{width:'100%'}}>
          <div style={{width:'100%', display:'flex', justifyContent:'center'}}>
            <div className="timeline-head" onClick={this.clickTitle(value)}>{value}</div>
          </div>
          {htmlbody}
          <div style={{height:'5px'}}>{}</div>
        </div>
      )
    })

    return(

      <div style={{flex:1,width:'100%',position:'relative',padding:'15px'}} ref={this.dom}>
        {html}
      </div>
    )
  }

  private clickTitle = (value:any) => {

    return () => {
      if (this.state.displayType === 'flex') {
        this.setState({
          displayType : 'none'
        })
      }else{
        this.setState({
          displayType : 'flex'
        })
      }
    }
  }

}

3.2、改进

改进思路:

当时思考了一下,认为有三种改进方法:
1、将时间title和展示数据的小模块提成一个小组件,这样小组件中的this.state.displaytype则可以分别代表对应日期数据的展示状态。
2、在生成map的时候可以加一个标记元素,当这个标记元素为ture则展示数据,为false不展示。 private clickTitle = (value:any) => {}方法根       据value来改变不同日期的标记元素。
3、dom操作,先获取到当前点击的div,再获到当前div的下级div,(即为该日期对应的展示数据)将其设为隐藏

改进说明:

我是按思路1改的。因为这种模式比较契合数据驱动ui的设计思路。另外两种方式,我觉得理论可行但未予以实践。如所述有错欢迎大家积极留言指正,如有什么疑问也欢迎各位同学留言讨论,我会尽量帮助你们弄明白。

改进后代码:

timelinebody.tsx为提取出来的小组件,timeline时间轴组件遍历map的时候生成timelinebody组件。这样每天展示数据的displaytype都是遍历生成的,可以达到点击日期,收起其对应的日期的数据的目的

时间轴:timeLine.tsx

import * as React from 'react';
import {format} from 'date-fns';
import PerfectScrollbar from 'perfect-scrollbar';
import { TimeLineBody } from './timeLineBody';

export interface IProps{
  data : any,
  leftImg : string,
  rightImg : string,
  color : string[],
  iconUrl : string,
  objectType : string,
  relationType : string
}

export interface IListType {
  objectaddress : string
  objectId : string
  objectTime : string
  unionaddress : string
  unionId : string
  unionTime : string

  entiyImg : string
  accompanyImg : string
}

export class TimeShaft extends React.PureComponent<IProps,any>{

  private dom: React.RefObject<HTMLDivElement> ;
  private scroller: PerfectScrollbar | undefined ;

  constructor(props:IProps){
    super(props);
    this.dom = React.createRef();
    this.state = {
      displayType : 'flex' ,
      objectType : this.props.objectType ,
      relationType : this.props.relationType
    }
  }

  public componentWillReceiveProps(nextProps:IProps){

    this.setState({
      relationId : nextProps.objectType,
      relationType: nextProps.relationType,
    });
    
  }

  // 组件渲染之后设置滚动条样式
  public componentDidMount() {
    const wrapper = this.dom.current;
    if (wrapper) {
      this.scroller = new PerfectScrollbar(wrapper, {
          wheelPropagation: false,
          wheelSpeed: 2,
      });
      this.updateScroller();
    }
  }
  // 组件更新后设置滚动条样式
  public componentDidUpdate() {
    this.updateScroller();
  }
  public updateScroller() {
    this.scroller!.update();
  }

  public render() {
    
    const { objectType, relationType } = this.state;
    const { data, leftImg, rightImg, color } = this.props;
    const body : any = [];
    // 定义一个map对象
    const map : Map<string,Array<[]>> = new Map<string,Array<[]>>();
    // 将data组装成map
    data.forEach((item:any, i:number) => {
      // 取时间的年月日 dateTitle,作为map的键
      const dateTitle = format(item.entityTime, 'YYYY-MM-DD');
      // 如果map的键值对中没有 dateTitle,则set一个并创建一个空数组存储值
      if(!map.has(dateTitle)){
        map.set(dateTitle,[]);
      }
      // 如果map中已有该键值对,往数组中push遍历的对象item
      const list = map.get(dateTitle);
      if(list){
        list.push(item);
      }
    });

    map.forEach((list, value) => {

      body.push(
        <TimeLineBody
          leftImg = {leftImg}
          rightImg = {rightImg}
          color = {color}
          objectType = {objectType}
          relationType = {relationType}
          list = {list}
          value = {value}
        />
      )
 
    })

    return(
      <div style={{flex:1,width:'100%',position:'relative'}} ref={this.dom}>
        {body}
      </div>
    )
  }

}

提取出来的小组件:timeLineBody.tsx

import * as React from 'react';
import {format} from 'date-fns';
import PerfectScrollbar from 'perfect-scrollbar';
import {Text} from '../../common/text';
import { IconFont } from '../../common/iconFont';

export interface IProps{
  leftImg : string,
  rightImg : string,
  color : string[],
  objectType : string,
  relationType : string,

  list : any,
  value : any,
}

export interface IListType {
  objectaddress : string
  objectId : string
  objectTime : string
  unionaddress : string
  unionId : string
  unionTime : string

  entiyImg : string
  accompanyImg : string
}

export class TimeLineBody extends React.PureComponent<IProps,any>{

  constructor(props:IProps){
    super(props);
    this.state = {
      displayType : 'flex' ,
      objectType : this.props.objectType ,
      relationType : this.props.relationType
    }
  }

  public componentWillReceiveProps(nextProps:IProps){

    this.setState({
      objectType : nextProps.objectType,
      relationType: nextProps.relationType,
    });
    
  }

  public render() {

    const { displayType,objectType,relationType } = this.state;
    const { leftImg,rightImg,color,list,value } = this.props;

    const html : any = [] ;
    const datalist : IListType[] = [] ;
    // htmlbody要写在foreach循环里面,如果写全局变量最后会把全部结果push进去
    const htmlbody : any = [] ;

    list.forEach((item:any, num :number) => {
      datalist.push({
        objectaddress : item.entitySpace,
        objectId : item.entityID ,
        objectTime : item.entityTime,
        unionaddress : item.accompanySpace,
        unionId : item.accompanyID,
        unionTime : item.accompanyTime,

        entiyImg : item.entiyImg ,
        accompanyImg : item.accompanyImg ,
      })

      htmlbody.push(
        <div style={{display:displayType, width:'100%'}}>
          {/* 左 */}
          <div className="shaft-htmlbody-main" style={{ justifyContent:'flex-end'}}>
            <div className="shaft-htmlbody-dif" style={{ marginRight:'10px' }}>
              <div className="shaft-htmlbody-border" style={{ border:'1px solid' + color[0] }}>

                <div className="shaft-htmlbody-smallTitle" style={{backgroundColor:color[0]}}>
                  <img className="shaft-htmlbody-img" src={leftImg} alt=""/>
                  <div className="shaft-htmlbody-font">
                    { objectType  === '01' 
                      ? <Text widths="120px" data={datalist[num].objectId.slice(0,7)}/> 
                      : <Text widths="120px" data={datalist[num].objectId}/> }
                  </div>
                </div>

                <div className="shaft-htmlbody-dataImg">
                  <img style={{ width:'100%' }} src={datalist[num].entiyImg}/>
                </div>

                <div className="shaft-htmlbody-time">
                  <div style={{width:'40%'}}>过卡时间:</div>
                  <Text widths="60%" data={format(datalist[num].objectTime, 'HH:mm:ss')}/>
                </div>

                <div className="shaft-htmlbody-space">
                  <div style={{width:"40%"}}>卡口地点:</div>
                  <Text widths="60%" data={datalist[num].objectaddress}/>
                </div>

              </div>
            </div>
          </div>
          
          {/* 中间icon */}
          <div style={{width: 2, display:'flex', flexDirection:'column'}}>
            <div style={{width: 2, backgroundColor: '#e6e6e6',height:30}}>{}</div>
            <div style={{width: 2, height:32}}>
              <IconFont extraCommonProps={ {style:{fontSize:30,color:'#b3b3b3',marginLeft:-15}} } type="iconshijian2" />
            </div>
            <div style={{width: 2, backgroundColor: '#e6e6e6', flex:'1'}}>{}</div>
          </div>

          {/* 右 */}
          <div className="shaft-htmlbody-main" style={{ justifyContent:'flex-start'}}>
            <div className="shaft-htmlbody-dif" style={{marginLeft:'10px'}}>
              <div className="shaft-htmlbody-border" style={{ border:'1px solid'+color[1] }}>

                <div className="shaft-htmlbody-smallTitle" style={{ backgroundColor:color[1] }}>
                  <img className="shaft-htmlbody-img" src={rightImg} alt=""/>
                  <div className="shaft-htmlbody-font">
                    { relationType  === '01' 
                      ? <Text widths="120px" data={datalist[num].unionId.slice(0,7)}/> 
                      : <Text widths="120px" data={datalist[num].unionId}/> }
                  </div>
                </div>

                <div className="shaft-htmlbody-dataImg">
                  <img style={{ width:'100%' }} src={datalist[num].accompanyImg}/>
                </div>

                <div className="shaft-htmlbody-time">
                  <div style={{width:"40%"}}>过卡时间:</div>
                  <Text widths="60%" data={format(datalist[num].unionTime, 'HH:mm:ss')}/>
                </div>

                <div className="shaft-htmlbody-space">
                  <div style={{width:'40%'}}>卡口地点:</div>
                  <Text widths="60%" data={datalist[num].unionaddress}/>
                </div>

              </div>
            </div>
          </div>

        </div>
      )
    })
    // 按value值循环生成htmlbody后,再生成html模块
    html.push(
      <div style={{width:'100%'}}>

        <div style={{width:'100%', display:'flex', justifyContent:'center'}}>
          <div className="timeline-head" onClick={this.clickTitle(value)}>{value}</div>
        </div>

        {htmlbody}

        <div style={{height:'5px'}}>{}</div>

      </div>
    )
   

    return(
      <div style={{flex:1,width:'100%',position:'relative',padding:'15px'}} >
        {html}
      </div>
    )
  }

  private clickTitle = (value:any) => {

    return () => {
      if (this.state.displayType === 'flex') {
        this.setState({
          displayType : 'none'
        })
      }else{
        this.setState({
          displayType : 'flex'
        })
      }
    }
  }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

定制化开发——时间轴组件 的相关文章

  • Java基础怎么样才算牢固,能熟练使用还是深入源码?

    java就是一门工具 本质上跟你开的车没什么区别 java的熟练程度 就犹如你的驾驶技术 本质上就是工具操作的熟练度 对于工具的操作而言 绝大多数人 会用就行了 源码基本上没有深入的必要 因为对于绝大多数程序员以及非程序员而言 这个轮不到你
  • B端产品的交互设计流程探索:乐高设计法和用户体验的二次提升

    面对突如其来的B端体验设计的挑战 可以解决吗 或者说设计师的思路该如何针对B端设计的特点进行调整 甚至设计管理的思路如何调整 一起来文章中看看解决办法 如何应对B端到来的挑战 随着互联网常规C端业务逐渐由蓝海转为红海 B端设计迎来了各种挑战
  • VS-SQL 连接DBHelper类

    using System using System Collections Generic using System Data using System Data SqlClient using System Text using Syst

随机推荐

  • 阿里云实习生部门笔试2020.04

    月初申请阿里c c 实习生 公司很快安排了上机笔试 是两道算法题大题 很难 没刷过题导致题目也看不怎么懂 笔试完第二天阿里云打电话安排另一场笔试 题目如下 评测题目 无 第一题 char str http www ibegroup com
  • python 题(附答案)

    1 一行代码实现1 100之和 gt gt 5050 2 描述 join 和split 区别 join用来连接字符串 split恰好相反拆分字符串 gt gt my name is huihui gt gt my name is huihu
  • vba可以放服务器上处理文档,当Word Doc位于服务器上时,如何从Excel VBA更改Word Doc中的文本?...

    我有一个宏 可以根据单词模板创建实验报告 然后将其保存到远程服务器 在我的Excel工作表中选择一个单元格 运行宏 使用空白模板打开Word实例 并根据所选单元格和其他数据保存文件 我想要做的是编辑空白模板中的标题 并将其更新为实验名称 该
  • 70进货卖100利润是多少_服装批发利润大揭秘!让你拿货砍价心里有个底

    你以为服装批发档口卖货的策略是薄利多销 你以为一包货只要小几百元很便宜 错 不要用零售的价格参考服装批发的价格 服装批发还可以更便宜 只要你了解服装批发商的利润空间 你就知道他们的价格底线在哪 拿货砍价更有目标 首先 我们从服装在市场上的来
  • python高性能服务器编写,Tornado的高性能服务器开发常用方法

    最近一直开发AI人脸识别相关的项目 需要提供给客户一些服务 所以我需要开发一些服务端程序 由于AI算法都是用python3写的 所以我就索性用起了python开发服务端 毕竟速度也快 以前用过Flask Django 这次决定有Tornad
  • 编译与链接

    把C 当脚本语言写 https www cnblogs com index html archive 2012 07 28 cppscript html vc 调用exe时 如何获取exe的输出信息 输出显示在IDE的输出中 http bl
  • [Python人工智能] 五.theano实现神经网络正规化Regularization处理

    从本系列文章开始 作者正式开始研究Python深度学习 神经网络及人工智能相关知识 前四篇文章讲解了神经网络基础概念 Theano库的安装过程及基础用法 theano实现回归神经网络 theano实现分类神经网络 这篇文章讲解Overfit
  • Hibenate技术详解

    一 Hibernate的基本用法 1 Hibernate的数据库操作 在所有的ORM框架中有一个非常重要的媒介 PO Persistence Object 持久化对象 持久化对象的作用是完成持久化操作 简单的说 通过该对象可以对数据进行增删
  • 逻辑回归介绍及statsmodels、sklearn实操

    目录 1 逻辑回归简要介绍 2 statsmodels中实现逻辑回归 3 sklearn实现逻辑回归 3 1 基础案例代码 3 2 样本不平衡问题处理 3 3 LogisticRegression模型参数说明 3 4 模型调优方法 1 逻辑
  • java 获取两个日期之间的所有月份 (年月)、以及月数、年数

    获取两个日期之间的所有月份 年月 param startTime param endTime return YYYY MM public static List
  • 347. 前 K 个高频元素

    1 哈希记录元素出现次数 2 放入优先队列 最大堆 3 依次出队获取结果 public class Solution public int TopKFrequent int nums int k 收集元素次数 Dictionary
  • linux内核设置选择硬件,Linux内核中USB充电器的解决方案

    当前最新的内核 v3 5 对USB充电器的整体方案支持的不是太好 这里讨论的USB充电器的方案仅指软件 方案 即充电器的检测需要由软件干预 比如读取USB PHY的寄存器 同时电池的充电值根据 充电器的不同类型 需要由软件来设置 硬件检测充
  • 导学:从提笔就怕,到写什么都赚钱

    做最懂技术的传播者 最懂传播的工程师 课程内容分析 课程的标题非常 标题党 实际课件的标题收敛很多 如何为系统学习新媒体写作做准备 正式开始课程前的建议 本节课程为正式课程开始前的一节导论课程 主要目的是 使学员明确 新媒体写作内容提升的学
  • k8s 系列之 CoreDNS 解读

    k8s 系列之 CoreDNS CoreDNS工作原理 kuberntes 中的 pod 基于 service 域名解析后 再负载均衡分发到 service 后端的各个 pod 服务中 如果没有 DNS 解析 则无法查到各个服务对应的 se
  • CMake 学习笔记(设置C++ 标准的版本)

    CMake 学习笔记 设置C 标准的版本 C 标准发展至今已经有很多个版本 包括最开始 C 98 后面的 C 11 C 14 C 17 等 如果我们的代码用到了比较新的C 特性 那么就需要编译器有对应的支持 这篇博客主要就是讲讲如何告诉 C
  • swift手动导入OC的第三方库

    声明 作为ios开发的新语言 相对比较oc 资源还是比较欠缺 有时候开发中 我们需要引入第三方库就不得不引入oc版的第三方库 然后苹果公司也给集成了这样的快捷方式 导入第三方的方法有 1 CocoaPods 2 手动将第三方的文件复制到工程
  • 双栈排序java_数据结构和算法-栈

    1 栈 Stack 的介绍 栈是一个先入后出 FILO First In Last Out 的有序列表 栈 Stack 是限制线性表中元素的插入和删除只能在同一端进行的一种特殊线性表 允许插入和删除的一端 为变化的一端 称为栈顶 Top 另
  • system表空间用满解决 方法

    早上看到alert日志报说system表空间快满了 oracle版本是11gR2 如果system表空间不是自动扩展 空间用满甚至会出现 数据库无法登陆 使用任何用户登录均报出异常 系统表空间正常情况下只存放了数据字典之类的东西 所以占用的
  • 漏洞分析|Adobe ColdFusion 序列化漏洞(CVE-2023-29300)

    0x01 概述 近期 Adobe ColdFusion 发布了多个安全更新 引起了我们的关注 Adobe ColdFusion 是一款基于 Java 的商业应用程序服务器 2023 年 7 月 13 日 ProjectDiscovery 发
  • 定制化开发——时间轴组件

    文章目录 一 需求 二 思路 三 代码 3 1 第一版代码 3 2 改进 改进思路 改进说明 改进后代码 一 需求 1 开发一个展示轨迹数据用的时间轴组件 2 后端传入是一个 list 数据格式如下 const dataRalation e