当前位置:   article > 正文

vxe-table中vxe-grid(高级表格)的使用

vxe-grid

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

  1. <vxe-grid
  2. ref='xGrid'
  3. v-bind="gridOptions"
  4. @cell-click="cellClickEvent" //设置表格编辑方式点击列触发该方法是点击某列时触发的方法
  5. @edit-closed="editClosedEvent"> //当被编辑的列失去焦点时即为编辑结束,触发该方法
  6.     <template #product_item="{ data }"> //这里是动态配置表单项productList是从后台请求到的数据经过处理后要渲染到option中的值,value、label
  7. <vxe-select v-model="data.topic" placeholder="选择项目名称" transfer>
  8.     <vxe-option v-for="item in productList" :key="item.value" :value="item.value" :label="item.label" />
  9.     </vxe-select>
  10.     </template>
  11.     <template #operate_item="{ data }">
  12.     <vxe-button type="submit" status="primary" content="查询" />
  13.     <vxe-button type="reset" content="重置" @click="haha(data)" /> //文档中自带的重置按钮如果不拦截的话无法对自定义的表单数据进行操作,故这里需要自定义一个方法
  14.     </template>
  15. </vxe-grid>

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

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

重置按钮方法

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

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

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

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

  1. editClosedEvent ({ row, column }) {
  2. const $table = this.$refs.xGrid;
  3. const field = column.property;
  4. const cellValue = row[field];
  5. // 判断单元格值是否被修改
  6. if ($table.isUpdateByRow(row, field)) {
  7.     setTimeout(() => {
  8.     VXETable.modal.message({
  9.     content: `保存成功!`,
  10.     status: 'success'
  11.     })
  12.     // 局部更新单元格为已保存状态
  13.     $table.reloadRow(row, null, field)
  14.         // 保存数据后执行查询事件重新渲染表格数据,row就是你所编辑的行的数据,该处row的值是你编辑后的值
  15.         // 这里遇到一个问题是:下拉框选择值时只能拿到其value值,不像el-select中可以同时拿到label和value的值
  16.         // 由于时间紧我这里是拿到value值到后台数据库查询出其对应的lebel值再进行后续操作了,时间丰富的小伙伴可以深入研究一下
  17.     XEAjax.post(`${this.baseUrl}/updateOrder`, JSON.stringify(row)).then(
  18.     res => this.$refs.xGrid.commitProxy('query')
  19.     );
  20.     }, 300)
  21. }
  22. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/140540
推荐阅读
相关标签
  

闽ICP备14008679号