IT俱乐部 JavaScript vxe-table中vxe-grid(高级表格)的使用方法举例

vxe-table中vxe-grid(高级表格)的使用方法举例

官网传送门,废话不多说了,经过自己半个月左右的踩雷经历,发篇博客记录一下,方便自己也方便他人。由于项目需求时间问题,前面的表格都没看直接使用了vxe-grid高级表格,下面上代码。

1
2
3
//当被编辑的列失去焦点时即为编辑结束,触发该方法
      //这里是动态配置表单项productList是从后台请求到的数据经过处理后要渲染到option中的值,value、label
          //文档中自带的重置按钮如果不拦截的话无法对自定义的表单数据进行操作,故这里需要自定义一个方法

下面是核心代码写在data里,js,大部分配置官网上都有,可以找到对应API,我就着重写一下我踩雷的地方,代码中会有注释,请耐心观看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
gridOptions: {
    border:true,   //是否带边框
    stripe: true,   //是否带斑马纹
    round: true,   //边框是否圆角
    showHeaderOverflow: true,   //表头内容过长时是否显示省略号
    showOverflow: true,   //所有内容过长时是否显示省略号
    keepSource: true,   //是否保持原始值状态
    id: 'full_edit_1',   //唯一标识,某些功能会用到,我这里没有用到,可以忽略
    rowConfig: {   //行配置信息
      isHover: true
    },
    columnConfig: {   //列配置信息
      resizable: true
    },
    printConfig: {   //打印配置项,具体的看文档吧,很详细了,注意columns里的field要和实际数据的key对应上
      columns: [
        { field: 'name' },
        { field: 'email' },
        { field: 'nickname' },
        { field: 'age' },
        { field: 'amount' }
      ]
    },
    sortConfig: {   //排序配置项
      trigger: 'cell',
      remote: true
    },
    filterConfig: {   //筛选配置项
      remote: true
    },
    pagerConfig: {   //配置分页
      pageSize: 15,
      pageSizes: [5, 10, 15, 20, 50, 100, 200, 500, 1000],
      layouts: ['Sizes', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'FullJump', 'Total']
    },
    formConfig: {   //表单配置项:就是查询条件,items中的field一定要和实体类名称对应上,方便管理。这里只放一个input框和下拉框了,其他的自己探索吧,API里都有
      titleWidth: 100,
      titleAlign: 'right',
      items: [
        {
          field: 'topic',
          title: '项目名称',
          span: 4,
          slots: {
            default: 'product_item'   //这里要和上面动态配置的表单项名称对应
          }
        },
        {
          field: 'status',
          title: '状态',
          span: 4,
          folding: false,
          itemRender: {
            name: '$select',
            options: [
              { label: '待处理', value: '待处理' },
              { label: '处理中', value: '处理中' },
              { label: '已计划', value: '已计划' },
              { label: '已完成', value: '已完成' },
              { label: '已关闭', value: '已关闭' }
            ],
            props: { placeholder: '请选择项目状态' }
          }
        },
        { span: 24, align: 'center', slots: { default: 'operate_item' } }   //查询重置按钮
      ]
    },
    toolbarConfig: {   //工具栏配置项
      // 这种写法是官方文档写法,只会执行API中对应的方法,若想自己实现按钮功能需要自定义插槽,如下
      // buttons: [
      //   { code: 'delete', status: 'danger', name: '直接删除', icon: 'vxe-icon-delete' },
      // ],
      // 自定义插槽
      slots: {
        buttons: ({ row }) => {
          return  this.showDialog()}>新建工单 this.$refs.xGrid.commitProxy('delete')} style="margin-left: 10px;">直接删除
        }
      },
      refresh: true,
      import: true,
      export: true,
      print: true,
      zoom: true,
      custom: true
    },
    proxyConfig: {   //数据代理配置项
      seq: true, // 启用动态序号代理,每一页的序号会根据当前页数变化
      sort: true, // 启用排序代理,当点击排序时会自动触发 query 行为
      filter: true, // 启用筛选代理,当点击筛选时会自动触发 query 行为
      form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
      // 对应响应结果 { result: [], page: { total: 100 } }
      props: {
        result: 'result', // 配置响应结果列表字段
        total: 'page.total' // 配置响应结果总页数字段
      },
      // 只接收Promise,具体实现自由发挥
      ajax: {
        // 当点击工具栏查询按钮或者手动提交指令 query或reload 时会被触发
        query: ({ page, sorts, filters, form }) => {
          const queryParams = Object.assign({}, form)
          // 处理排序条件
          const firstSort = sorts[0]
          if (firstSort) {
            queryParams.sort = firstSort.property
            queryParams.order = firstSort.order
          }
          // 处理筛选条件
          filters.forEach(({ property, values }) => {
            queryParams[property] = values.join(',')
          })
          queryParams.page = page.currentPage;
          queryParams.pageSize = page.pageSize;
          //自己在data中定义个baseUrl,用来访问后台
          return XEAjax.post(`${this.baseUrl}/queryOrder`, queryParams)
        },
        // 当点击工具栏删除按钮或者手动提交指令 delete 时会被触发
        delete: ({ body }) => {
          return XEAjax.post(`${this.baseUrl}/deleteOrder`, JSON.stringify(body.removeRecords));
        },
        // 当点击工具栏保存按钮或者手动提交指令 save 时会被触发(用自带的添加按钮的话会用到这个保存事件,我这里已经自定义插槽按钮事件了,故将该处注释掉,而且需要实时保存的话也用不上这个按钮)
        // save: ({ body }) => {
        //   return XEAjax.post(`${this.baseUrl}/updateOrder`, JSON.stringify(body.updateRecords)).then(
        //     res => xxx
        //   );
        // }
      }
    },
    columns: [   //列配置:将在这里显示数据,field要和实体类名称对应上
      { type: 'checkbox', field: 'id', title: '工单序号' },   //多选框
      { field: 'title',  title: '标题' },
      {
        field: 'status',
        title: '状态',
        width: 95,
        slots: {   //该处展示自定义插槽,可以将数据封装到想用的组件里,视觉效果更佳
          default: ( {row} ) => {
            if (row.status == '待处理') {
              return {row.status};
            }
            if (row.status == '处理中') {
              return {row.status};
            }
            if (row.status == '已计划') {
              return {row.status};
            }
            if (row.status == '已完成') {
              return {row.status};
            }
            if (row.status == '已关闭') {
              return {row.status};
            }
          }
        },
        filters: [   //配置筛选条件,配置后表头对应列会有筛选图标,点开即可操作
          { label: '待处理', value: '待处理' },
          { label: '处理中', value: '处理中' },
          { label: '已计划', value: '已计划' },
          { label: '已完成', value: '已完成' },
          { label: '已关闭', value: '已关闭' }
        ],
        filterMultiple: false,   //筛选是否可多选
        editRender: {   //该处是列可编辑状态下的编辑框,这里是一个静态下拉框,下面有一个动态下拉框也是我踩雷的地方
          name: '$select',
          options: [
            { label: '待处理', value: '待处理' },
            { label: '处理中', value: '处理中' },
            { label: '已计划', value: '已计划' },
            { label: '已完成', value: '已完成' },
            { label: '已关闭', value: '已关闭' }
          ],
          props: { placeholder: '请选择工单状态' }
        }
      },
      {   //该列是获取后台数据动态渲染到页面上的地方,踩雷好几天
        field: 'charger',
        title: '负责人',
        editRender: {
          name: '$select',
          props: {
            value: [],
            options: [],   //用来显示下拉框数据的地方
            optionProps: {   //下拉框option的配置,该处要有,否则点开下拉框选值的时候对应label不会高亮
              value: 'value',
              label: 'label'
            },
            multiple: true,   //可多选
            clearable: true,
            placeholder: '请选择负责人',
            optionConfig: {
              useKey: true
            }
          }
        },
        formatter: this.formatCharger
      },
      {   //自定义插槽可以自定义事件
        slots: {
          default: ({ row }) => {
            return  this.handleCell(row)}>详情
          }
        }
      }
    ],
    importConfig: {   //导入配置项,暂时没用到该功能没深入研究,API上都有
      remote: true,
      importMethod: this.importMethod,
      types: ['xlsx'],
      modes: ['insert']
    },
    exportConfig: {   //导出配置项,暂时没用到该功能没深入研究,API上都有
      remote: true,
      exportMethod: this.exportMethod,
      types: ['xlsx'],
      modes: ['current', 'selected', 'all']
    },
    checkboxConfig: {   //复选框配置项
      labelField: 'id',
      reserve: true,
      highlight: true,
      range: true
    },
    editRules: {   //列编辑规则
      charger: [
        { required: true, message: '负责人不能为空' }
      ]
    },
    editConfig: {   //可编辑配置项
      trigger: 'click',
      mode: 'cell',   //cell(单元格编辑模式),row(行编辑模式)
      showStatus: true
    }
  }

重置按钮方法

1
2
3
4
haha(val) {
  //这里可以看到所有表单配置中的值
  console.log(val);
}

下面是列编辑是如果是下拉框如何请求后台接口获取数据,并渲染到页面上,写到method里,该处就是用到了上面的单元格点击事件

1
2
3
4
5
6
7
8
//如果进页面就请求后台数据渲染下拉框的话,它是没有数据的,我也在网上找了很多解决办法,要么找不到,要么代码写的没头没尾的,很不友好
//点击列的时候判断列属性,如果是想要编辑的那个列再去后台请求数据,然后以下拉框的格式返回给option就有数据了
cellClickEvent({row, column}) {
  if (column.property == 'charger') {
    let list = [];
    // 该处是请求后台的方法,封装在别处了,直接用axios去请求也可
    getAllTeamUser(param).then(res => {
      for (let i = 0; i

下面是列编辑完后失去焦点自动保存的方法,也是写在method里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
editClosedEvent ({ row, column }) {
  const $table = this.$refs.xGrid;
  const field = column.property;
  const cellValue = row[field];
  // 判断单元格值是否被修改
  if ($table.isUpdateByRow(row, field)) {
      setTimeout(() => {
        VXETable.modal.message({
          content: `保存成功!`,
          status: 'success'
        })
        // 局部更新单元格为已保存状态
        $table.reloadRow(row, null, field)
        // 保存数据后执行查询事件重新渲染表格数据,row就是你所编辑的行的数据,该处row的值是你编辑后的值
        // 这里遇到一个问题是:下拉框选择值时只能拿到其value值,不像el-select中可以同时拿到label和value的值
        // 由于时间紧我这里是拿到value值到后台数据库查询出其对应的lebel值再进行后续操作了,时间丰富的小伙伴可以深入研究一下
        XEAjax.post(`${this.baseUrl}/updateOrder`, JSON.stringify(row)).then(
          res => this.$refs.xGrid.commitProxy('query')
        );
      }, 300)
  }
}

vxe-grid 表格头标题设置及内容合并列项

附:vxe-grid 表格头标题设置及内容合并列项

1、vxe-grid 表格的高级使用: 自定义表格表头标题动态添加,内容列有合并项;实现效果如下所示:

 2、vxe-grid 代码部分设置,实现合并有两种方式可以根据情况自由选定合并方式,代码如下;

1
2
3
<span class="bl-center">{{ row.xh }}</span>
                <span class="bl-left">{{ row.xh }}</span>
            <span class="bl-center"> {{ DictSearch(row, column) }} </span>

3、js 数据设置及方法设置实现,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// 数据内容设置
data(){
      return {
        fxList: [],
        table:{
            loading: false,
            mergeCells:[],
            rightMenu: {
                className: 'my-menus',
                body: {
                    options: [
                        [
                            { code: 'addRowOne', name: '新增' },
                            { code: 'handleDelete', name: '删除' },
                        ]
                    ]
                },
            },
            isEdit: false,
            editConfig: {
                trigger: 'click',
                mode: 'cell',
                showIcon:false,
                activeMethod : this.activeCellMethod
            },
            columns: [
            { title: '任务工作台',
                align: 'center',
                children: [] , //注:其他表格头设置在 children 内设置列项即可
            }
            ], 
            dataSource: [],
        },
      }
  },
  
// 方法设置
        // 通用行合并函数(将相同多列数据合并为一行)
       mergeRowMethod({ row, _rowIndex, column, visibleData }) {
           let that = this
           // console.log(row, _rowIndex, column, visibleData, '_rowIndex, column, visibleData')
           let col_span = that.table.columns[0].children.length || 0
            if(row.isDictType == true){
                return { rowspan: 1, colspan: col_span }
            }  
       },
       // 计算合并列
       computMecall(dataSource, headList){
            this.table.mergeCells = []
            const headL = headList.length || 0
            const tabal_data = dataSource
            let MergeCell_row = 0
            let itemMergeCell = { row: MergeCell_row, rowspan: 1, colspan: headL, col: 0 }
            tabal_data.forEach((bitem, u)=>{
                if(bitem.isDictType){
                    itemMergeCell = { row: u, rowspan: 1, colspan: headL, col: 0 }
                    this.table.mergeCells.push(itemMergeCell)
                }
            }) 
       },
       // 查字典
       DictSearch(row, column) {
            let res = '' 
            if(column.field in row){
                res = row[column.field] 
                this.fxList.forEach(item => {
                    if(item.value == res){
                        res = item.text
                    }
                })
            }
            return res
        },
   /********** 其他方法此处略过,具体根据项目需求设定处理即可...... *********/

以上内容仅供参考!

总结 

到此这篇关于vxe-table中vxe-grid(高级表格)使用方法的文章就介绍到这了,更多相关vxe-table vxe-grid高级表格使用内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/navsub/js/11094.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部