前端页面表格控件handsontable在vue项目中的应用

handsontable是目前在前端界最接近excel的插件,可以执行编辑,复制粘贴,插入删除行列,排序等复杂操作。拥有jQuery、react、ng和vue版本,功能强大,是复杂表格的不二之选。

下面介绍一下handsontable表格控件在vue项目中的使用方法:

1.安装模块包

npm install handsontable-pro @handsontable-pro/vue

npm install handsontable @handsontable/vue

这样安装完handsontable依赖的各模块(moment、numbro、pikaday 、zeroclipboard)也一起安装完了,不必再单独安装

页面如果使用相关的模块方法,可以直接import引入,例如使用moment中的格式化时间方法:

import moment from "moment"

formatTime(time){
 return moment(time).format('YYYY-MM-DD HH:mm:ss')
}
formatTime(new Date())
  1. 引入模块包

import { HotTable } from '@handsontable-pro/vue'
import '../../node_modules/handsontable-pro/dist/handsontable.full.css'
import Handsontable from 'handsontable-pro'

  1. 引入组件
<template>
  <div>
    <div id="hotTable" class="hotTable">
        <HotTable  ref="testHot" :settings="hotSettings"></HotTable>
    </div>
   </div>
  </template>
  1. api参数说明
export default {
  data: function () {
    return {
      
      root: 'test-hot',
      
      hotSettings: {
        
        data: [        //数据可以是二维数组,也可以是数组对象
          
          ['20080101', 10, 11, 12, 13,true],
          
          ['20090101', 20, 11, 14, 13,true],
          
          ['20010101', 30, 15, 12, 13,true],
          
          ['20010101', 32, 213, 21, 312,true],
          
          ['20010201', 32, 213, 21, 312,true],
          
          ['20010301', 32, 213, 21, 312,true],
          
          ['20010401', 32, 213, 21, 312,true],
          
          ['20010501', 32, 213, 21, 312,true],
          
          ['20010601', 32, 213, 21, 312,true]
        
        ],
        
        startRows: 11,//行列范围
        
        startCols: 6,
        
        minRows: 5,  //最小行列
        
        minCols: 5,
        
        maxRows: 20,  //最大行列
        
        maxCols: 20,
        
        rowHeaders: true,//行表头,可以使布尔值(行序号),可以使字符串(左侧行表头相同显示内容,可以解析html),也可以是数组(左侧行表头单独显示内容)。
        
        colHeaders:   [ '题目', 'A选项', 'B选项', 'C选项', 'D选项','答案'],//自定义列表头or 布尔值
        
        minSpareCols: 2, //列留白
        
        minSpareRows: 2,//行留白
        
        currentRowClassName: 'currentRow', //为选中行添加类名,可以更改样式
        
        currentColClassName: 'currentCol',//为选中列添加类名
        
        autoWrapRow: true, //自动换行
        
        contextMenu: {   //自定义右键菜单,可汉化,默认布尔值
          
          items: {
            
            "row_above": {
              
              name:'上方插入一行'
              
            },
            
            "row_below": {
              
              name:'下方插入一行'
              
            },
            
            "col_left": {
              
              name:'左方插入列'
              
            },
            
            "col_right": {
              
              name:'右方插入列'
              
            },
            
            "hsep1": "---------", //提供分隔线
            
            "remove_row": {
              
              name: '删除行',
              
            },
            
            "remove_col": {
              
              name: '删除列',
              
            },
            
            "make_read_only": {
              
              name: '只读',
              
            },
            
            "borders": {
              
              name: '表格线',
              
            },
            
            "commentsAddEdit": {
              
              name: '添加备注',
              
            },
            
            "commentsRemove": {
              
              name: '取消备注',
              
            },
            
            "freeze_column": {
              
              name: '固定列',
              
            },
            
            "unfreeze_column": {
              
              name: '取消列固定',
              
            },
            
            "hsep2": "---------",
            
          }
          
        },//右键效果
        
        fillHandle: true, //选中拖拽复制 possible values: true, false, "horizontal", "vertical"
        
        fixedColumnsLeft: 0,//固定左边列数
        
        fixedRowsTop: 0,//固定上边列数
        
        mergeCells: [   //合并
          
          {row: 1, col: 1, rowspan: 3, colspan: 3},  //指定合并,从(1,1)开始行3列3合并成一格
          
          {row: 3, col: 4, rowspan: 2, colspan: 2}
        
        ],
        
        columns: [     //添加每一列的数据类型和一些配置
          
          {
            
            //data: 'title', 此设置标识,数组对象数据格式时的列字段
            
            type: 'date',   //时间格式
            
            dateFormat: 'YYYYMMDD',
            
            correctFormat: true,
            
            defaultDate: '19000101'
            
          },
          
          {
            
            type: 'dropdown', //下拉选择
            
            source: ['BMW', 'Chrysler', 'Nissan', 'Suzuki', 'Toyota', 'Volvo'],
            
            strict: false   //是否严格匹配
            
          },
          
          {type: 'numeric'},  //数值
          
          {type: 'numeric',
            
            readOnly: true  //设置只读
            
          },
          
          { type: 'numeric',
            
            format: '$ 0,0.00'},  //指定的数据格式
          
          {type: 'checkbox'},  //多选框
        
        ],
        
        afterChange: function (changes, source) { //数据改变时触发此方法
          
          console.log(this.getData());
          
        },
        
        manualColumnFreeze: true, //手动固定列
        
        manualColumnMove: true, //手动移动列
        
        manualRowMove: true,   //手动移动行
        
        manualColumnResize: true,//手工更改列距
        
        manualRowResize: true,//手动更改行距
        
        comments: true, //添加注释
        
        cell: [
          
          {row: 1, col: 1, comment: {value: 'this is test'}},
        
        ],
        
        customBorders:[],//添加边框
        
        columnSorting: true,//排序
        
        stretchH: 'all',//根据宽度横向扩展,last:只扩展最后一列,none:默认不扩展
        
      }
      
    };
    
  },
  
  name: 'handsonTable',
  
  components: {
    
    HotTable
    
  },
  
  methods: {
    
    saveData (){
      
      var examData = this.$refs.testHot.table.getData(); //这里要注意,如果使用this.hotSettings.data 保存表格数据,拖拽完以后数据的顺序将不会更新,因此使用 this.$refs.testHot.table.getData(); 来获取数据,获取的数据格式为二维数组。
      
      console.log(examData );
      
    }
    
  }
  
}
  1. 完整示例
import { HotTable } from '@handsontable-pro/vue'
import '../../node_modules/handsontable-pro/dist/handsontable.full.css'
import Handsontable from 'handsontable-pro'

<template>
  <div>
    <div id="hotTable" class="hotTable">
        <HotTable :root="root" ref="testHot" :settings="hotSettings"></HotTable>
     </div>
  </div>
</template>

  <script>
export default {
  data: function () {
    return {
      root: 'test-hot',
      hotSettings: {
        data: [        //数据可以是二维数组,也可以是数组对象
          ['20080101', 10, 11, 12, 13,true],
          ['20090101', 20, 11, 14, 13,true],
          ['20010101', 30, 15, 12, 13,true],
          ['20010101', 32, 213, 21, 312,true],
          ['20010201', 32, 213, 21, 312,true],
          ['20010301', 32, 213, 21, 312,true],
          ['20010401', 32, 213, 21, 312,true],
          ['20010501', 32, 213, 21, 312,true],
          ['20010601', 32, 213, 21, 312,true]
        ],
        startRows: 11,//行列范围
        startCols: 6,
        minRows: 5,  //最小行列
        minCols: 5,
        maxRows: 20,  //最大行列
        maxCols: 20,
        rowHeaders: true,//行表头,可以使布尔值(行序号),可以使字符串(左侧行表头相同显示内容,可以解析html),也可以是数组(左侧行表头单独显示内容)。
        colHeaders:   [ '题目', 'A选项', 'B选项', 'C选项', 'D选项','答案'],//自定义列表头or 布尔值
        minSpareCols: 2, //列留白
        minSpareRows: 2,//行留白
        currentRowClassName: 'currentRow', //为选中行添加类名,可以更改样式
        currentColClassName: 'currentCol',//为选中列添加类名
        autoWrapRow: true, //自动换行
        contextMenu: {   //自定义右键菜单,可汉化,默认布尔值
          items: {
            "row_above": {
              name:'上方插入一行'
            },
            "row_below": {
              name:'下方插入一行'
            },
            "col_left": {
              name:'左方插入列'
            },
            "col_right": {
              name:'右方插入列'
            },
            "hsep1": "---------", //提供分隔线
            "remove_row": {
              name: '删除行',
            },
            "remove_col": {
              name: '删除列',
            },
            "make_read_only": {
              name: '只读',
            },
    { type: 'numeric',
      format: '$ 0,0.00'},  //指定的数据格式
    {type: 'checkbox'},  //多选框
  ],
    afterChange: function (changes, source) { //数据改变时触发此方法
      console.log(this.getData());
    },
    manualColumnFreeze: true, //手动固定列
      manualColumnMove: true, //手动移动列
      manualRowMove: true,   //手动移动行
      manualColumnResize: true,//手工更改列距
      manualRowResize: true,//手动更改行距
      comments: true, //添加注释
      cell: [
      {row: 1, col: 1, comment: {value: 'this is test'}},
    ],
      customBorders:[],//添加边框
      columnSorting: true,//排序
      stretchH: 'all',//根据宽度横向扩展,last:只扩展最后一列,none:默认不扩展
  }
  };
  },
    name: 'handsonTable',
      components: {
      HotTable
    },
    methods: {
      saveData (){
        var examData = this.$refs.testHot.table.getData(); //这里要注意,如果使用this.hotSettings.data 保存表格数据,拖拽完以后数据的顺序将不会更新,因此使用 this.$refs.testHot.table.getData(); 来获取数据,获取的数据格式为二维数组。
        console.log(examData );
      }
    }
  }
  </script> 

  1. handsontable 插件事件api

1)afterChange (changes: Array, source: String):1个或多个单元格的值被>改变后调用

changes:是一个2维数组包含row,prop,oldVal,newVal4个属性。

source:其值为一个字符串,值可以为:alter,empty,>populateFromArray,loadData,autofill,paste

2)beforeChange (changes: Array, source: String):开始改变单元格前被>调用

changes:是一个2维数组,包括[row,prop,oldVal,newVal]这4个公共属>性列

source是被改变的资源的名称

3)afterCellMetaReset ():重置单元格后调用

4)afterColumnMove (oldIndex: Number, newIndex: Number):列顺序被>>移动后触发

5)afterRowMove (oldIndex: Number, newIndex: Number):行被移动后调>用

6)afterRowResize (col: Number, size: Number):行高改变后调用

7)afterRemoveCol (index: Number, amount: Number):当一列或多列被>移动后调用

其中,index为开始移动的列的索引,amount为移动的列的总数量

8)afterRemoveRow (index: Number, amount: Number):当一行或多行被>移动后调用

其中,index为被移动的行的索引,amount为被移动的行的总数量

9)beforeRemoveCol (index: Number, amount: Number):一列或多列被>>移动前调用beforeRemoveRow (index: Number, amount: Number):一行或>多行被移动前被调用

10)afterColumnSort (column: Number, order: Boolean):列排序后调用

11)beforeColumnSort (column: Number, order: Boolean):列排序前被调用

order:值为true时为升序,false时为降序

12)afterCreateCol (index: Number, amount: Number):添加行后被调用

index:新列的索引

amount:新列的数目

13)afterCreateRow (index: Number, amount: Number):添加行后被调用

index:新行的索引

amount:新行的数目

14)afterGetCellMeta (row: Number, col: Number, cellProperties: >Object):获取单元格的配置信息后被调用

15)beforeGetCellMeta (row: Number, col: Number, cellProperties: >Object):获取单元格属性前被调用

16)afterSetCellMeta(row: Number, col: Number, key: String, value: *):单>元格样式被改变后调用

其中,cellProperties是一个单元格的渲染对象,key是改变样式的方式,例>如合并单元格(merge),水平对齐(align)等。

17)afterGetColHeader (col: Number, TH: DOM Node):获取列头信息后被>调用,TH是行头节点

18)afterGetColWidth (col: Number, response: Object):获取列宽后被调用

19)afterColumnResize (col: Number, size: Number):列宽度被手动修改后调用

20)afterCopyLimit (s-electedRowsCount: Number, s-electedColsCount: Number,copyRowsLimit: Number, copyColsLimit: Number)

当 copyRowsLimit 或者 copyColumnsLimit实现时被调用

21)afterDestroy ():销毁Handsontable实例后被调用

22)afterInit ():Handsontable实例被初始化后调用

23)beforeInit ():Handsontable实例被初始化前调用

24)beforeInitWalkontable():Walkontable实例被初始化前调用

25)afterLoadData ():新的数据被加载到数据资源后被调用afterOnCellCornerMouseDown (event):鼠标点击单元格边角后被调用

26)afterOnCellMouseDown (event: Object, coords: Object, TD: Object):>点击单元格或行头/列头后被调用

注意:点击行头或列头后索引的坐标为负数。例如点击列头单元格(0,0),则>调用后的坐标为(0,-1)。

27)afterOnCellMouseOver (event: Object, coords: Object, TD: Object):鼠标>停悬在单元格或行头/列头后调用

注意:点击行头或列头后索引的坐标为负数。例如点击行头单元格(0,0),>则调用后的坐标为(0,-1)。

28)afterRender (isForced: Boolean):渲染表格后被调用

isForced:当其值为true表示是通过改变配置或数据引起的渲染,当值为>false时表示通过滚动或移动、选中引起的渲染

29)beforeRender (isForced: Boolean):渲染前被调用

30)afterRenderer (TD: Object, row: Number, col: Number, prop: String, >value: String, cellProperties: Object):手动渲染后调用

31)beforeChangeRender ():渲染被改变前调用

32)afterDes-elect ():当前单元格被取消选中时调用

33)afterS-election (r: Number, c: Number, r2: Number, c2: Number):当>一个或多个单元格被选中后调用

其中,r:选中的单元格起始行,r2:选中单元格的终止行

c:选中的单元格的起始列,c2:选中的单元格的终止列

34)afterS-electionByProp (r: Number, p: String, r2: Number, p2: String):>通过属性名选中单元格后调用afterS-electionEnd (r: Number, c: Number, r2: >Number, c2: Number):选中单元格鼠标抬起后调用

afterS-electionEndByProp (r: Number, p: String, r2: Number, p2: String):通>过属性选中单元格鼠标抬起后调用

35)afterUpdateSettings ():配置参数配修改后调用

36)afterValidate (isValid: Boolean, value: Mixed, row: Number, prop: >String,source: String)

当有验证器的时候调用验证器时被调用,验证结果作为第一个参数。

37)beforeValidate (value: Mixed, row: Number, prop: String, source: >String):验证器被调用前调用该事件

38)beforeAutofill (start: Object, end: Object, data: Array):开始自动填充前调动

start:是一个第一个填充的单元格对象,例如:{row:4,col:3}

end:是最后一个填充的单元格对象,例如:{row:7,col:5}

data:是一个2维数组

39)beforeKeyDown (event: Object):按键按下前被调用

40)beforeSet (var: Object):单个配置值被设置前调用
41)beforeSetRangeEnd(coords: Array):设置范围结束前被调用

coords:是范围坐标

42)modifyCol(col: Number):列被修改时调用

43)modifyRow( row: Number):行被修改时调用

44)modifyColWidth (width: Number, col: Number):列宽被修改时调用

45)modifyRowHeight (height: Number, row: Number):行高被修改时调用

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,050评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,538评论 1 306
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,673评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,622评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,047评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,974评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,129评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,893评论 0 209
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,654评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,828评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,297评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,619评论 3 262
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,326评论 3 243
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,176评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,975评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,118评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,909评论 2 278

推荐阅读更多精彩内容