定制网站Vxe-Table的各种坑,以及避坑指南(需要补充的请留言)

背景:

定制网站由于公司要开发erp,定制网站采用了做为UI基础框架,定制网站但是回想往事点点滴滴,element-ui定制网站表格的种种表现令人痛心,于是跟leader定制网站商量之后决定使用Vxe-Table定制网站做表格插件,虽然element-plus定制网站在表格上也在大力优化,定制网站但就目前来看可用度确实不高,定制网站刚出了一个虚拟滚动,定制网站但看上去确实让人有点心急。。。

定制网站开发阶段遇到的各种问题

全局size的问题

定制网站有点扯犊子的事,我element-plus定制网站定制网站要做全局的size修改,定制网站那就意味着我的表格也要做全局的size修改,定制网站庆幸的是它有自带的全局size配置,定制网站配置方法也很简单,在setup定制网站方法中设置即可,配合vuex、本地存储(包括cookie),还有模有样的可以搞一搞,不幸的是,这特么size跟element-plus的size规则天差地别,虽然可以通过修改变量去规避这个问题,但是成本属实有点高。而且element-plus的为large、default、small,但是的为下面是medium、small、mini还需要做判断,杂七杂八,有点小恶心。下面附上代码。

  1. import 'xe-utils'
  2. import VXETable from 'vxe-table'
  3. import 'vxe-table/lib/style.css'
  4. //引入font-awesome
  5. import 'font-awesome/css/font-awesome.css'
  6. import { localAppSizeKey } from '@/store/modules/settings/index'
  7. VXETable.setup({
  8. size: formatSize(localStorage.getItem(localAppSizeKey) || 'default') as any
  9. })
  10. export default function (app: any) {
  11. app.use(VXETable)
  12. // 给 vue 实例挂载内部对象,例如:
  13. // app.config.globalProperties.$XModal = VXETable.modal
  14. // app.config.globalProperties.$XPrint = VXETable.print
  15. // app.config.globalProperties.$XSaveFile = VXETable.saveFile
  16. // app.config.globalProperties.$XReadFile = VXETable.readFile
  17. }
  18. /**
  19. * 解析element-plus的全局size
  20. * @param size
  21. * @returns
  22. */
  23. function formatSize(size: null | undefined | string) {
  24. let resSize = 'small'
  25. switch (size) {
  26. case 'large':
  27. resSize = 'medium'
  28. break
  29. case 'default':
  30. resSize = 'small'
  31. break
  32. case 'small':
  33. resSize = 'mini'
  34. break
  35. }
  36. return resSize
  37. }

size是存在localStorage里面的,设置一次,更新一次值,我这里就很简单粗暴了,全局设置element-plus的size然后通过format方法解析,存入本地存储,然后刷新页面,啊哈哈哈哈,问就是还不知道咋搞,有人知道的麻烦私一个,解决这个问题。

按钮的问题

说真的,我很能理解作者的设计模式,我也很佩服作者的代码功底,毕竟我只是一个使用者,但是但是,你自己开发一套按钮什么的,能不能走点心嘛,按钮中的文字居然不能垂直居中。大哥这都啥年代了哎,附上我处理按钮垂直居中的代码

  1. .vxe-button.type--button {
  2. display: inline-flex;
  3. align-items: center;
  4. justify-content: center;
  5. }

简单粗暴,flex解决,有问题再解决

合并单元格的问题

单元格合并的按照官网提供的案例,第一次使用了spanMethod方法,那时候数据量少,没有开启虚拟滚动,后来数据量大了,测试滚动了一下叫了一声,我头皮一麻就知道出问题了,结果我看到官网上赫然写着,不支持虚拟滚动,哎~~ 我用这个表格不就是冲着虚拟滚动来的吗?再找解决方案把,后来决定还是用【mergeCells】去解决这个问题,解决思路就是,根据需求,合并固定的列,然后在数据中查询最近的相同数据(后端已排好序),生成要合并的数据,然后赋值到gridOptions对象上面,具体实现如下:

  1. proxyConfig: {
  2. seq: true,
  3. sort: true,
  4. filter: true,
  5. form: true,
  6. props: {
  7. result: 'data.data',
  8. total: 'data.totalCount'
  9. },
  10. ajax: {
  11. query: async ({ page, form }) => {
  12. const { pageSize: size, currentPage } = page
  13. const paging = { size, page: currentPage }
  14. const queryParams: any = Object.assign({ isOdm: 1 }, paging, form)
  15. const response = await queryList(queryParams)
  16. // 合并单元格选项
  17. let mergeCells: any[] = []
  18. mergeCells = generateMergeCells(
  19. response.data.data,
  20. 'spuName',
  21. [2, 3, 4, 5, 6, 7, 8]
  22. )
  23. gridOptions.mergeCells = mergeCells
  24. return response
  25. }
  26. }
  27. },

这时候第一页可以分页了,但是跳转页面后,发现问题了,第二页分页居然错乱?后面的全乱了!!大爷的。为此谷歌百度都查了,结果还是没有解决方案。后来突发奇想,每次分页我reload一下会不会好点,结果还真就行了,其实就是在前面代码中加入一行代码:xGrid.value.reloadData(response.data.data)

  1. proxyConfig: {
  2. seq: true,
  3. sort: true,
  4. filter: true,
  5. form: true,
  6. props: {
  7. result: 'data.data',
  8. total: 'data.totalCount'
  9. },
  10. ajax: {
  11. query: async ({ page, form }) => {
  12. const { pageSize: size, currentPage } = page
  13. const paging = { size, page: currentPage }
  14. const queryParams: any = Object.assign({ isOdm: 1 }, paging, form)
  15. const response = await queryList(queryParams)
  16. // 合并单元格选项
  17. let mergeCells: any[] = []
  18. mergeCells = generateMergeCells(
  19. response.data.data,
  20. 'spuName',
  21. [2, 3, 4, 5, 6, 7, 8]
  22. )
  23. gridOptions.mergeCells = mergeCells
  24. xGrid.value.reloadData(response.data.data)
  25. return response
  26. }
  27. }
  28. },

芜湖~~,解决!附上动态生成mergeCells的代码

  1. // 生成合并单元格数据
  2. export const generateMergeCells = (
  3. data: any[],
  4. key: string,
  5. cols: number[]
  6. ) => {
  7. if (data.length === 0) return []
  8. let pointer: number = 0
  9. let total: number = 0
  10. let curKeyValue: any = data[0][key]
  11. const result = data.reduce((acc: any[], cur: any, index: number) => {
  12. const val = cur[key]
  13. let mergeData: any = []
  14. if (val !== curKeyValue) {
  15. // 生成合并数据
  16. if (total > 1) {
  17. mergeData = generateCells(cols, pointer, total)
  18. }
  19. curKeyValue = val
  20. pointer = index // 指针index赋值
  21. total = 1
  22. } else {
  23. total += 1
  24. if (index === data.length - 1) {
  25. mergeData = generateCells(cols, pointer, total)
  26. }
  27. }
  28. acc.push(...mergeData)
  29. return acc
  30. }, [])
  31. return result
  32. }
  33. export const generateCells = (
  34. cols: number[],
  35. rowIndex: number,
  36. rowspan: number
  37. ) => {
  38. return cols.map((col: number) => {
  39. return {
  40. row: rowIndex,
  41. col,
  42. rowspan,
  43. colspan: 1
  44. }
  45. })
  46. }

reload和load的问题

我实在搞不懂为什么每次reload和load要传参数进去,而却重置和查询这种按钮的方法没有抛出来以供调用。

但是也可以解决,作者抛出了很多方法,但是说明文档里面没有...,具体可以参照node_modules/vxe-table/packages/src/grid.ts文件

  1. gridMethods.commitProxy('query')
  2. // insert
  3. // insert_actived
  4. // mark_cancel
  5. // remove
  6. // import
  7. // open_import
  8. // export
  9. // open_export
  10. // reset_custom
  11. // _init
  12. // 重置page 并查询
  13. gridMethods.commitProxy('_init')
  14. // reload
  15. // 重新载入,可以重置一些参数但并不能重置查询参数
  16. gridMethods.commitProxy('reload')
  17. // query
  18. // delete
  19. // save

grid在重置之后列表自动查询的时候还是会把原本的数据带过去的问题解决

在被坑的死去活来的时候,发现,grid的查询字段,如果ui不是自带的,这时候就会又有一个问题,那就是点击重置的时候,slots自定义的组件不能重置,后来发现有@form-reset的方法去重置,但是需要自己去写,这一点不是很友好,但是还可以接受

  1. <vxe-grid ref="xGrid"
  2. class="sl-main-wrapper"
  3. v-bind="gridOptions"
  4. @form-reset="gridformReset">
  5. ...
  6. </vxe-grid>
  1. const gridformReset = ({ data }) => {
  2. const keys = ['picker', 'stereotypeMaker', 'status']
  3. keys.forEach((i: any) => {
  4. data[i] = undefined
  5. })
  6. }

但是发现了一个问题,我第一次重置的时候,我重置后的值居然带不过去,它还是上一个条件的参数~~,我滴个亲哥,要命啊,找了很多解决方案,首先是代码次序,不行,再次是重新组织查询的参数,发现还是不行,后来在吃饭的时候想起来会不会是因为没有nextTick的原因呢?

果然是!!!!!!!!!!!!!!!!!!!!!!!!!

最后的解决方案是这样的:

以下代码只是我的场景,核心点是return nextTick(() => { return response })

  1. query: ({ page, form }) => {
  2. return nextTick(async () => {
  3. const { pageSize: size, currentPage } = page
  4. const paging = { size, page: currentPage }
  5. const queryParams: any = Object.assign(paging, form)
  6. const vxeForm = clone(queryParams, true)
  7. const picker = vxeForm.picker || []
  8. if (picker.length > 0) {
  9. if (form.dateType === 1) {
  10. vxeForm.tailorCompleteTimeStart = picker[0]
  11. vxeForm.tailorCompleteTimeEnd = picker[1]
  12. } else if (form.dateType === 2) {
  13. vxeForm.stereotypeCompleteTimeStart = picker[0]
  14. vxeForm.stereotypeCompleteTimeEnd = picker[1]
  15. }
  16. }
  17. delete vxeForm.picker
  18. delete vxeForm.dateType
  19. const response = await queryList(vxeForm)
  20. return response
  21. })
  22. }

VxeTable行编辑和 el-select和el-autocomplete的select事件冲突的问题

今天在开发行编辑时,因为行编辑查询要做远程查询,所以使用了el-autocomplete进行远程查询,但是发现,查询到了数据以后,点击选中时发现无法选中,令我很困惑,最后仔细查看了el-autocomplete这个组件的属性之后,发现popper-append-to-body属性默认是true(我记得好像是false。。。),原来是每次点击select触发了取消行编辑导致点击没有选中,触发了取消行编辑和关闭poper导致,将popper-append-to-body属性改为false即可。

  1. <el-autocomplete
  2. v-model="row.materialCode"
  3. value-key="code"
  4. placeholder=""
  5. clearable
  6. :fetch-suggestions="queryWllist"
  7. @select="(e) => selectWllist(e, row)"
  8. :popper-append-to-body="false"
  9. ></el-autocomplete>

其他问题

暂时还没想到,想到了再更新吧,有兄弟姐妹愿意跟我讨论的可以一起嗷~~

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发