Henry Henry
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)

Henry

小学生中的前端大佬
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)
  • JavaScript

  • TypeScript

  • Vue

  • ElementUI

    • 基于 ElementUI 封装的 TextEllipsis
    • 基于 ElementUI 封装的 Tree
    • 基于 ElementUI 封装的 Tree2
    • 基于 ElementUI 封装的 SelectTree
    • 基于 ElementUI 封装的 NumberInput
    • 基于 ElementUI 封装的基础 table 和 form
    • 基于 ElementUI 封装的 TreeTable
    • 基于 VuePress 搭建一个类似 ElementUI 的说明文档
    • el-tree 节点过滤加载对应子节点
    • 简单调试 node_modules 源码
    • ElementUI 问题集合
      • element-ui 消息提示全局修改
      • table 固定列不能拖动横向滚动条
      • tabs + table
      • 打包后 icon 不显示
        • 问题
        • 原因
        • 解决方法:
        • 参考资料
      • table current-row-key 无法高亮子节点
      • select 文本太长会超出选择框
      • table + pagination 序号问题
      • table formatter 问题
      • Pagination 分页
        • 问题
        • 解决
      • 利用 v-if 动态渲染表格时, 在 el-table-column 中添加 key 属性防止表格复用
      • 自定义滚动条
        • 问题一
        • 问题二
    • 树形表格更新后保持折叠状态
    • 开始和完成时间互相限制
  • React

  • AntD

  • 前端
  • ElementUI
Henry
2017-09-15
目录

ElementUI 问题集合

收集工作中使用 ElementUI 遇到的一些问题

# element-ui 消息提示全局修改 (opens new window)

# table 固定列不能拖动横向滚动条

element-ui: 2.13.2

关于这个 bug 在 issues 中有好几条:

  • [Bug Report] Table statistics, fixed columns cannot drag horizontal scrollbars (table statistics, fixed columns cannot drag horizontal scrollbars) · Issue #15471 · ElemeFE/element (opens new window)
  • [Bug Report] table has lock table header, lock table column, and can not scroll when combined. · Issue #12666 · ElemeFE/element (opens new window)

目前比较好的解决方法是这种:

@Eflet (opens new window)

.el-table {
  .el-table__fixed {
    pointer-events: none;
    > * {
      pointer-events: auto;
    }
  }
}
1
2
3
4
5
6
7
8

用 css 禁用掉鼠标事件, 然后下一层再全部放开鼠标事件, 目前没发现副作用

# tabs + table

如果使用 tabs 包裹 table 出现样式问题: 如切换 tabs 后, table 右侧出现一条滚动条滑槽, 但没有滚动条出现(实际上 table 确实不应该有滚动条) 等等, 可以尝试给 table 加一个 v-if="activeName === 'currentName. activeName 为 tabs 绑定值, currentName 为包裹该 table 的 tab-pane 的 name

# 打包后 icon 不显示

# 问题

ElementUI 自带了一套常用的图标集合, 使用起来十分方便. 最近发现当 Vue.js 项目中使用 ElementUI 图标时, 如果使用 npm run dev 方式启动, 图标是显示正常的; 而一旦使用 npm run build 编译打包后发布到服务器上, 会发现图片显示不出来( Chrome 浏览器下显示方块)

# 原因

查看 /build/webpack.base.conf.js 文件可以发现, woff 或 ttf 这些字体会经由 url-loader 处理后在 static/fonts 目录下生成相应的文件

也就是说实际应该通过 /static/fonts/ 路径来获取字体图标, 而实际却是请求 /static/css/static/fonts/, 自然报 404 错误.

# 解决方法:

# 方法一

打开 build/utils.js 文件, 在如下位置添加 publicPath: '../../'

if (options.extract) {
  return ExtractTextPlugin.extract({
    use: loaders,
    fallback: 'vue-style-loader',
    publicPath: '../../'
  })
} else {
  return ['vue-style-loader'].concat(loaders)
}
1
2
3
4
5
6
7
8
9

# 方法二

在 build/webpack.base.conf.js 中添加

module: {
  rules: [
    ...(config.dev.useEslint ? [createLintingRule()] : []),
    {
      test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
      loader: 'url-loader',
      options: {
        limit: 10000,
        publicPath: '../../',
        name: utils.assetsPath('fonts/[name].[hash:7].[ext]'),
      },
    },
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 参考资料

  • Element-ui 项目打包后 icon 图标不显示_JavaScript_weixin_41346436 的博客-CSDN 博客 (opens new window)
  • elementUI 中 icon 在 webpack 打包后不显示的问题 - Jocelee - 博客园 (opens new window)

# table current-row-key 无法高亮子节点

element-ui: 2.13.0

官方文档:

参数 说明 类型 可选值 默认值
current-row-key 当前行的 key, 只写属性 String, Number --- ---

具体问题请看[Bug Report] el-table current-row-key can't highlight children · Issue #19067 · ElemeFE/element (opens new window)

如果 current-row-key 为父节点 key , 那么可以高亮, 如果为子节点 key , 无法高亮

目前只能使用 setCurrentRow 来实现默认高亮子节点了:

this.$nextTick(() => {
  this.$refs.table.setCurrentRow(this.defaultCurrentRow)
})
1
2
3

# select 文本太长会超出选择框

element-ui: 2.13.0

具体问题: 当选择某一个文本内容太长的选项后, 选择的文本会超出选择框, 如下图所示:

overflow

When the [Bug Report] select component is multiple-selected, the text is too long and the display box overflows. · Issue #15473 · ElemeFE/element (opens new window)

解决方法:

@kissu 提出一种解决方案:

.el-tag--info {
  display: flex !important;
  max-width: 100% !important;
}

.el-select__tags-text {
  display: inline-block !important;
  max-width: 90% !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}

.el-tag__close {
  align-self: center !important;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

但 collapse-tags 仍然有一点问题:

collapse-tags

# table + pagination 序号问题

目前 ElementUI(1.4.4) 使用 table + pagination 时, el-table-column 设置 type="index" 点击下一页后, 序号没有对应按照上一页的数据继续增加, 而是直接显示为 1, 2, 3, ...

本文是在基于 @yuanshengchao 在 Element issues (opens new window) 中提出的方案进行优化 (其实就是照搬)

具体代码去看链接就可以了, 有可能当你看到本文时, Element 团队已经处理好这个问题了

# table formatter 问题

使用 formatter 时, 按照官方给出的例子, 第三个参数永远是 undefined , 如果需要对所有列都 format (逻辑是一样的), 则需要每一列都写一个函数, 将需要 format 的参数传入, 这样无疑是没有意义的

具体问题 (opens new window)

解决 (opens new window)

例子:

<el-table-column
  align="center"
  prop="createDate"
  :formatter="(row, column) => formatTime(row, column, 'createDate')"
  label="创建日期"
  min-width="150"
>
</el-table-column>

<!-- 一般 column 不常用,只需要传入需要格式化的值即可,即下面这种写法 -->

<el-table-column
  align="center"
  prop="publishDate"
  :formatter="row => formatTime(row.publishDate)"
  label="发布时间"
  min-width="100"
>
</el-table-column>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
methods: {
  formatTime (value, type) {
    if (value == null || value === '') {
      return ''
    }
    type = type || 'YYYY-MM-DD'
    return this.$moment(value).format(type)
  }
}
1
2
3
4
5
6
7
8
9

# Pagination 分页

# 问题

废话不多说, 先看图

注: 在 current-change 事件会调 fetchDesign 方法

如图, 原意是想在发请求前将 total 置为 0 , 即初始值, 请求成功后根据返回的值来改变 total , 这样就不用写 else 和 catch 了

结果就出问题了, 不论点击第几页, 永远会跳回第一页. 比如点击第四页, current-change 事件会触发两次, 第一次的回调参数是 4 , 而第二次就是 1 , 所以会永远跳回第一页

结果就去 https://github.com/ElemeFE/element/issues/ . 发现一个 和我类似的 (opens new window)

其中 @huguangju 的话点醒了我, 原文:

删除 jumper 中的数字后, 当前页跳到第 1 页并不是点击 next 直接导致的, 而是 jumper 失焦后其值此时为空字符串, 应用值到 internalCurrentPage 前会校验设置的页码, 部分源码如下, 会被设置为 1 :

getValidCurrentPage(value) {
  value = parseInt(value, 10);
  // ...
  if (resetValue === undefined && isNaN(value)) {
    resetValue = 1; // here
  } else if (resetValue === 0) {
    resetValue = 1;
  }
  return resetValue === undefined ? value : resetValue;
}
1
2
3
4
5
6
7
8
9
10

因为每次触发 current-change 事件都会调用 fetchDesign 方法, 而在这个方法中都将 total 置为 0 , 这样由于要校验设置的页码, 比如点击第四页, 当前为 4 , 而 total 为 0 , 总数是 0 , 哪来的第四页, 所以就被置为 1 了.

# 解决

那就不能图省事, 在发请求前就将 total 置为 0 , 而是根据请求返回来改变 total 的值. 如图:

# 利用 v-if 动态渲染表格时, 在 el-table-column 中添加 key 属性防止表格复用

先上代码

<div class="monitor-container">
  <el-card class="box-card">
    <div slot="header" class="clearfix">
      <el-tabs @tab-click="handleClick" v-model="monitorActiveName">
        <el-tab-pane label="海康监控" name="0"></el-tab-pane>
        <el-tab-pane label="萤石监控" name="1"></el-tab-pane>
      </el-tabs>
      <el-button style="float: right;" type="primary" icon="plus" @click="addMonitor">
        {{ addTxt }}
      </el-button>
    </div>
  </el-card>
  <el-table :data="monitorData" border :row-class-name="toggleColor" style="width:100%">
    <el-table-column
      v-if="monitorActiveName === '0'"
      align="center"
      prop="ipAddress"
      label="视频监控地址"
      min-width="150"
    >
    </el-table-column>
    <el-table-column
      v-if="monitorActiveName === '0'"
      align="center"
      prop="webPort"
      label="Web 端口号"
      min-width="150"
    >
    </el-table-column>
    <el-table-column
      v-if="monitorActiveName === '0'"
      align="center"
      prop="userName"
      label="用户名"
      min-width="150"
    >
    </el-table-column>
    <el-table-column
      v-if="monitorActiveName === '0'"
      align="center"
      prop="deviceName"
      label="设备名称"
      min-width="150"
    >
    </el-table-column>
    <el-table-column
      v-if="monitorActiveName === '1'"
      align="center"
      prop="appKey"
      label="appKey"
      min-width="150"
    >
    </el-table-column>
    <el-table-column
      v-if="monitorActiveName === '1'"
      align="center"
      prop="appSecret"
      label="appSecret"
      min-width="150"
    >
    </el-table-column>
    <el-table-column align="center" label="操作" width="150">
      <template slot-scope="scope">
        <el-button type="text" class="el-icon-edit" @click="editRow(scope.$index, scope.row)">
        </el-button>
        <el-button type="text" class="el-icon-delete" @click="deleteRow(scope.$index, scope.row)">
        </el-button>
      </template>
    </el-table-column>
  </el-table>
</div>
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

解释一下, 有两个监控列表: 海康和萤石, 通过一个 tab 切换来显示, 使用 v-if 来动态控制表格的显隐

具体问题看下图:

页面加载完成后, 可以正常显示, 顺序也和代码是一致的

切换到萤石后:

现在已经可以看出来顺序和代码不一致了

再切到海康:

设备名称和用户名对调了

以后再切换也都是这个顺序了

萤石那个还可以解决, 我代码顺序反一下就可以保证 appKey 在前面, appSecret 在后面, 但海康没办法, 就算一开始把用户名和设备名称对调, 切换一次后又对调了

可以看一下下面这个动图, 发现是代码复用了:

这时想到 v-for 通过添加 key 来唯一标识遍历后生成的对象, 这里是不是也可以这么做

修改后的代码:

<el-table-column
  v-if="monitorActiveName === '0'"
  key="ipAddress"
  align="center"
  prop="ipAddress"
  label="视频监控地址"
  min-width="150"
>
</el-table-column>
1
2
3
4
5
6
7
8
9

这里就贴出一部分, 其余的都是添加了一个 key 属性, 只要每个 el-table-column 的 key 值不一样就行, 这里是和 prop 保持一致, 完美解决了

# 自定义滚动条

介绍: Vue 的自定义滚动, 我用 el-scrollbar (opens new window)

使用: vue element 隐藏组件滚动条 scrollbar 使用 (opens new window)

# 问题一

以下为我自己设置的全局样式

.el-scrollbar {
  height: 100%;
  /* margin-right 配合下面的 padding-right 使用, 防止滚动条遮挡内容 */
  margin-right: -10px;
}

/* 查看官方网站发现是 auto, 而且也能隐藏掉横向的滚动条, 那就用 auto 吧 */
.el-scrollbar .el-scrollbar__wrap {
  overflow-x: auto;
}

.el-scrollbar__view {
  padding-right: 10px;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

但由于这个滚动条是 Element Ui 内部使用的, 目前发现就 el-select-dropdown 中在使用, 随意修改全局样式肯定会影响人家原有样式的. 比如这样:

下拉框最后一个显示不全, hover 后超出界线框

目前解决办法就三种:

  1. 不修改全局样式, 局部修改样式, 哪里使用滚动条哪里修改, 但毕竟需要滚动条的地方比 select-dropdown 要多, 不划算
  2. 封装成组件, 在组件内部修改, 但这已经是一个组件了, 有点画蛇添足
  3. 还是修改全局样式, 只不过在 select-dropdown 中重写样式, 使用原来的样式
/* 修改 scrollbar 在 select 下显示不全问题 */
.el-select-dropdown {
  .el-scrollbar {
    height: auto;
    margin-right: 0;

    .el-scrollbar__wrap {
      overflow: scroll;

      .el-scrollbar__view {
        padding-right: 0;
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 问题二

如果布局使用的是百分比布局, 那使用滚动条也会有问题.

比如两个子元素高度都是 50% , 如果使用 el-scrillbar 包裹子元素的话, 子元素的父元素会变成 el-scrollbar__view , 而这个元素是没有设置高度的, 会导致子元素的 50% 失效, 从而被内容撑开, 解决办法就是给 el-scrollbar__view 设置高度为 100%

编辑 (opens new window)
#ElementUI
上次更新: 5/27/2023, 1:02:05 PM
简单调试 node_modules 源码
树形表格更新后保持折叠状态

← 简单调试 node_modules 源码 树形表格更新后保持折叠状态→

最近更新
01
version 1.15
07-01
02
version 1.14
06-27
03
version 1.13
06-27
更多文章>
Theme by Vdoing | Copyright © 2017-2023 HenryTSZ | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式