美文网首页
基于react-grid-layout实现可视化拖拽

基于react-grid-layout实现可视化拖拽

作者: Bilif | 来源:发表于2019-05-14 13:48 被阅读0次

    前言

    做前端的小伙伴们可能会经常遇到做一个自定义dashboard这样的需求。
    那么什么是自定义dashboard呢?自定义dashboard其实就是一个自定义面板,用户能够在面板上自由的拖拽,新增,删除组件。组件可以是各种echarts图形,也可是各种数据表格。通过各个组件的拖拽组合,从而让用户自定义想要看到的面板。

    项目预览

    demo地址
    源码地址

    QQ20190514-131658-HD-compress.gif
    组件可以动态添加,删除,可以自由拖拽,缩放。并且缩放后组件内部的echarts图表也会跟着缩放。

    技术架构

    1. 前端框架:React
    2. UI库:Ant Design
    3. 脚手架:create-react-app
    4. 拖拽插件:react-grid-layout

    技术实现

    1. 使用npm安装react-grid-layout包
    npm install react-grid-layout
    
    2. 插件声明及样式引入

    首先,在js文件中引入WidthProvider和Responsive组件,并且实例化响应式拖拽组件。
    其次,在css文件中引入插件的样式。

    import { WidthProvider, Responsive } from "react-grid-layout";
    const ResponsiveReactGridLayout = WidthProvider(Responsive);
    
    @import '~react-grid-layout/css/styles.css';
    @import '~react-resizable/css/styles.css';
    
    3. Render渲染

    在React的render方法中渲染可拖拽布局。ResponsiveReactGridLayout组件有多个属性,这里举几个比较重要的说明一下:

    • cols:定义了响应式布局划分成几列。
    • rowHeight:响应式布局中组件的行高。
    • onLayoutChange:当响应式布局中的组件发生拖拽或者放大缩小时触发该函数。
    <ResponsiveReactGridLayout
        className="layout"
        {...this.props}
        layouts={this.state.layouts}
        onLayoutChange={(layout, layouts) =>
                  this.onLayoutChange(layout, layouts)
                }
       >
         {this.generateDOM()}
    </ResponsiveReactGridLayout>
    
    4.组件DOM生成

    通过generateDOM函数生成布局中的组件,首先先遍历组件数组,通过每个组件的类型判断生产柱状图组件,折线组件,还是饼图组件。每个组件必须定义一个全局唯一的key值。data-grid为每一个组件绑定了其属性。下面会介绍具体的data-grid属性。

     generateDOM = () => {
        return _.map(this.state.widgets, (l, i) => {
          let option;
          if (l.type === 'bar') {
            option = getBarChart();
          }else if (l.type === 'line') {
            option = getLineChart();
          }else if (l.type === 'pie') {
            option = getPieChart();
          }
          let component = (
            <ReactEcharts
              option={option}
              notMerge={true}
              lazyUpdate={true}
              style={{width: '100%',height:'100%'}}
            />
          )
          return (
            <div key={l.i} data-grid={l}>
              <span className='remove' onClick={this.onRemoveItem.bind(this, i)}>x</span>
              {component}
            </div>
          );
        });
      };
    
    5. 通过addItem函数来新增组件。

    每个组件属性如下:

    • x: 组件在x轴坐标
    • y: 组件在y轴坐标
    • w: 组件宽度
    • h: 组件高度
    • i: 组件key值
    addItem(type,widgetId) {
        const addItem = {
          x: (this.state.widgets.length * 2) % (this.state.cols || 12),
          y: Infinity, // puts it at the bottom
          w: 2,
          h: 2,
          i: widgetId || new Date().getTime().toString(),
        };
        this.setState(
          {
            widgets: this.state.widgets.concat({
              ...addItem,
              type,
            }),
          },
        );
      };
    
    6. 通过onRemoveItem函数来移除增组件。
    onRemoveItem(i) {
        console.log(this.state.widgets)
        this.setState({
          widgets: this.state.widgets.filter((item,index) => index !=i)
        });
    
      }
    

    后记

    感谢支持。若不足之处,欢迎大家指出,共勉。

    如果觉得不错,记得 点赞,谢谢大家 😂

    欢迎关注 我的:【Blog】【Github】【掘金】【简书】

    相关文章

      网友评论

          本文标题:基于react-grid-layout实现可视化拖拽

          本文链接:https://www.haomeiwen.com/subject/bewvoqtx.html