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)
目前比较好的解决方法是这种:
.el-table {
.el-table__fixed {
pointer-events: none;
> * {
pointer-events: auto;
}
}
}
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)
}
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]'),
},
},
]
}
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 | --- | --- |
如果 current-row-key
为父节点 key
, 那么可以高亮, 如果为子节点 key
, 无法高亮
目前只能使用 setCurrentRow
来实现默认高亮子节点了:
this.$nextTick(() => {
this.$refs.table.setCurrentRow(this.defaultCurrentRow)
})
2
3
# select 文本太长会超出选择框
element-ui: 2.13.0
具体问题: 当选择某一个文本内容太长的选项后, 选择的文本会超出选择框, 如下图所示:
解决方法:
@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;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
但 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
的参数传入, 这样无疑是没有意义的
例子:
<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>
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)
}
}
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;
}
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>
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>
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;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
但由于这个滚动条是 Element Ui
内部使用的, 目前发现就 el-select-dropdown
中在使用, 随意修改全局样式肯定会影响人家原有样式的. 比如这样:
下拉框最后一个显示不全, hover
后超出界线框
目前解决办法就三种:
- 不修改全局样式, 局部修改样式, 哪里使用滚动条哪里修改, 但毕竟需要滚动条的地方比
select-dropdown
要多, 不划算 - 封装成组件, 在组件内部修改, 但这已经是一个组件了, 有点画蛇添足
- 还是修改全局样式, 只不过在
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;
}
}
}
}
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%
- 01
- 搭配 Jenkins 实现自动化打包微前端多个项目09-15
- 02
- 自动化打包微前端多个项目09-15
- 03
- el-upload 直传阿里 oss 并且显示自带进度条和视频回显封面图06-05