Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
Element
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
CI / CD Analytics
Repository Analytics
Value Stream Analytics
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
林焕东
Element
Commits
14495f61
Commit
14495f61
authored
Oct 27, 2016
by
FuryBean
Committed by
cinwell.li
Oct 27, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Table: add filter feature. (#684)
parent
5a6cca14
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
569 additions
and
70 deletions
+569
-70
CHANGELOG.md
CHANGELOG.md
+1
-0
examples/docs/zh-cn/table.md
examples/docs/zh-cn/table.md
+96
-5
packages/table/src/dropdown.js
packages/table/src/dropdown.js
+27
-0
packages/table/src/filter-panel.vue
packages/table/src/filter-panel.vue
+180
-0
packages/table/src/table-body.js
packages/table/src/table-body.js
+1
-19
packages/table/src/table-column.js
packages/table/src/table-column.js
+18
-11
packages/table/src/table-header.js
packages/table/src/table-header.js
+65
-15
packages/table/src/table-store.js
packages/table/src/table-store.js
+36
-3
packages/table/src/table.vue
packages/table/src/table.vue
+2
-1
packages/table/src/util.js
packages/table/src/util.js
+18
-0
packages/theme-default/src/index.css
packages/theme-default/src/index.css
+1
-0
packages/theme-default/src/table-column.css
packages/theme-default/src/table-column.css
+85
-0
packages/theme-default/src/table.css
packages/theme-default/src/table.css
+24
-13
src/locale/lang/en.js
src/locale/lang/en.js
+6
-0
src/locale/lang/zh-cn.js
src/locale/lang/zh-cn.js
+6
-0
test/unit/specs/table.spec.js
test/unit/specs/table.spec.js
+3
-3
No files found.
CHANGELOG.md
View file @
14495f61
...
...
@@ -14,6 +14,7 @@
-
修复 Switch 的 width 属性无效的问题
-
Table 增加 rowClassName 属性
-
TableColumn 增加 fixed 属性,可选值:true, false, left, right
-
TableColumn 增加属性:filters、filterMultiple、filterMethod、filteredValue
-
TableColumn
[
type="selection"
]
增加 selectable 属性
-
修复 Input textarea 在动态赋值时 autosize 没有触发的问题
-
修复 Input Number min max 属性设置后点击加减出现的崩溃的bug
...
...
examples/docs/zh-cn/table.md
View file @
14495f61
...
...
@@ -9,28 +9,32 @@
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
zip: 200333,
tag: '家'
}, {
date: '2016-05-02',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
zip: 200333,
tag: '公司'
}, {
date: '2016-05-04',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
zip: 200333,
tag: '家'
}, {
date: '2016-05-01',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
zip: 200333,
tag: '公司'
}],
tableData2:
[
{
date: '2016-05-02',
...
...
@@ -119,6 +123,10 @@
return row.address;
},
filterTag(value, row) {
return row.tag === value;
},
tableRowClassName(row, index) {
if (index === 1) {
return 'info-row';
...
...
@@ -810,6 +818,85 @@
```
:::
### 筛选
对表格进行筛选,可快速查找到自己想看的数据。
:::demo 在列中设置
`filters``filter-method`
属性即可开启该列的筛选,filters 是一个数组,
`filter-method`
是一个方法,它用于决定某些数据是否显示,会传入两个参数:
`value`
和
`row`
。
```
html
<template>
<el-table
:data=
"tableData"
border
style=
"width: 100%"
>
<el-table-column
prop=
"date"
label=
"日期"
sortable
width=
"180"
>
</el-table-column>
<el-table-column
prop=
"name"
label=
"姓名"
width=
"180"
>
</el-table-column>
<el-table-column
prop=
"address"
label=
"地址"
:formatter=
"formatter"
>
</el-table-column>
<el-table-column
prop=
"tag"
label=
"标签"
width=
"100"
:filters=
"[{ text: '家', value: '家' }, { text: '公司', value: '公司' }]"
:filter-method=
"filterTag"
inline-template
>
<el-tag
:type=
"row.tag === '家' ? 'primary' : 'success'"
close-transition
>
{{row.tag}}
</el-tag>
</el-table-column>
</el-table>
</template>
<script>
export
default
{
data
()
{
return
{
tableData
:
[{
date
:
'
2016-05-02
'
,
name
:
'
王小虎
'
,
address
:
'
上海市普陀区金沙江路 1518 弄
'
,
tag
:
'
家
'
},
{
date
:
'
2016-05-04
'
,
name
:
'
王小虎
'
,
address
:
'
上海市普陀区金沙江路 1517 弄
'
,
tag
:
'
公司
'
},
{
date
:
'
2016-05-01
'
,
name
:
'
王小虎
'
,
address
:
'
上海市普陀区金沙江路 1519 弄
'
,
tag
:
'
家
'
},
{
date
:
'
2016-05-03
'
,
name
:
'
王小虎
'
,
address
:
'
上海市普陀区金沙江路 1516 弄
'
,
tag
:
'
公司
'
}]
}
},
methods
:
{
formatter
(
row
,
column
)
{
return
row
.
address
;
},
filterTag
(
value
,
row
)
{
return
row
.
tag
===
value
;
}
}
}
</script>
```
:::
### Table Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- |
...
...
@@ -853,3 +940,7 @@
| align | 对齐方式 | String | left, center, right | left |
| selectable | 仅对 type=selection 的列有效,类型为 Function,Function 的返回值用来决定这一行的 CheckBox 是否可以勾选 | Function(row, index) | - | - |
| reserve-selection | 仅对 type=selection 的列有效,类型为 Boolean,为 true 则代表会保留之前数据的选项,需要配合 Table 的 clearSelection 方法使用。 | Boolean | - | false |
| filters | 数据过滤的选项,数组格式,数组中的元素需要有 text 和 value 属性。 | Array
[
{ text, value }
]
| — | — |
| filter-multiple | 数据过滤的选项是否多选 | Boolean | — | true |
| filter-method | 数据过滤使用的方法,如果是多选的筛选项,对每一条数据会执行多次,任意一次返回 true 就会显示。 | Function(value, row) | — | — |
| filteredValue | 选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性。 | Array | — | — |
\ No newline at end of file
packages/table/src/dropdown.js
0 → 100644
View file @
14495f61
var
dropdowns
=
[];
document
.
addEventListener
(
'
click
'
,
function
(
event
)
{
dropdowns
.
forEach
(
function
(
dropdown
)
{
var
target
=
event
.
target
;
if
(
!
dropdown
||
!
dropdown
.
$el
)
return
;
if
(
target
===
dropdown
.
$el
||
dropdown
.
$el
.
contains
(
target
))
{
return
;
}
dropdown
.
handleOutsideClick
&&
dropdown
.
handleOutsideClick
(
event
);
});
});
export
default
{
open
(
instance
)
{
if
(
instance
)
{
dropdowns
.
push
(
instance
);
}
},
close
(
instance
)
{
var
index
=
dropdowns
.
indexOf
(
instance
);
if
(
index
!==
-
1
)
{
dropdowns
.
splice
(
instance
,
1
);
}
}
};
packages/table/src/filter-panel.vue
0 → 100644
View file @
14495f61
<
template
>
<transition
name=
"md-fade-bottom"
>
<div
class=
"el-table-filter"
v-if=
"multiple"
v-show=
"showPopper"
>
<div
class=
"el-table-filter__content"
>
<el-checkbox-group
class=
"el-table-filter__checkbox-group"
v-model=
"filteredValue"
>
<el-checkbox
v-for=
"filter in filters"
:label=
"filter.value"
>
{{
filter
.
text
}}
</el-checkbox>
</el-checkbox-group>
</div>
<div
class=
"el-table-filter__bottom"
>
<button
@
click=
"handleConfirm"
:class=
"
{ 'is-disabled': filteredValue.length === 0 }"
:disabled="filteredValue.length === 0">
{{
$t
(
'
el.table.confirmFilter
'
)
}}
</button>
<button
@
click=
"handleReset"
>
{{
$t
(
'
el.table.resetFilter
'
)
}}
</button>
</div>
</div>
<div
class=
"el-table-filter"
v-else
v-show=
"showPopper"
>
<ul
class=
"el-table-filter__list"
>
<li
class=
"el-table-filter__list-item"
:class=
"
{ 'is-active': !filterValue }"
@click="handleSelect(null)">
{{
$t
(
'
el.table.clearFilter
'
)
}}
</li>
<li
class=
"el-table-filter__list-item"
v-for=
"filter in filters"
:label=
"filter.value"
:class=
"
{ 'is-active': isActive(filter) }"
@click="handleSelect(filter.value)" >
{{
filter
.
text
}}
</li>
</ul>
</div>
</transition>
</
template
>
<
script
type=
"text/jsx"
>
import
Popper
from
'
element-ui/src/utils/vue-popper
'
;
import
Locale
from
'
element-ui/src/mixins/locale
'
;
import
Clickoutside
from
'
element-ui/src/utils/clickoutside
'
;
import
Dropdown
from
'
./dropdown
'
;
import
ElCheckbox
from
'
element-ui/packages/checkbox
'
;
import
ElCheckboxGroup
from
'
element-ui/packages/checkbox-group
'
;
export
default
{
name
:
'
el-table-filter-panel
'
,
mixins
:
[
Popper
,
Locale
],
directives
:
{
Clickoutside
},
components
:
{
ElCheckbox
,
ElCheckboxGroup
},
props
:
{
placement
:
{
type
:
String
,
default
:
'
bottom-end
'
}
},
customRender
(
h
)
{
return
(
<
div
class
=
"
el-table-filter
"
>
<
div
class
=
"
el-table-filter__content
"
>
<
/div
>
<
div
class
=
"
el-table-filter__bottom
"
>
<
button
on
-
click
=
{
this
.
handleConfirm
}
>
{
this
.
$t
(
'
el.table.confirmFilter
'
)
}
<
/button
>
<
button
on
-
click
=
{
this
.
handleReset
}
>
{
this
.
$t
(
'
el.table.resetFilter
'
)
}
<
/button
>
<
/div
>
<
/div>
)
;
},
methods
:
{
isActive
(
filter
)
{
return
filter
.
value
===
this
.
filterValue
;
},
handleOutsideClick
()
{
this
.
showPopper
=
false
;
},
handleConfirm
()
{
this
.
confirmFilter
(
this
.
filteredValue
);
this
.
handleOutsideClick
();
},
handleReset
()
{
this
.
filteredValue
=
[];
this
.
confirmFilter
(
this
.
filteredValue
);
this
.
handleOutsideClick
();
},
handleSelect
(
filterValue
)
{
this
.
filterValue
=
filterValue
;
if
(
filterValue
)
{
this
.
confirmFilter
(
this
.
filteredValue
);
}
else
{
this
.
confirmFilter
([]);
}
this
.
handleOutsideClick
();
},
confirmFilter
(
filteredValue
)
{
this
.
table
.
store
.
commit
(
'
filterChange
'
,
{
column
:
this
.
column
,
values
:
filteredValue
});
}
},
data
()
{
return
{
table
:
null
,
cell
:
null
,
column
:
null
};
},
computed
:
{
filters
()
{
return
this
.
column
&&
this
.
column
.
filters
;
},
filterValue
:
{
get
()
{
return
(
this
.
column
.
filteredValue
||
[])[
0
];
},
set
(
value
)
{
if
(
this
.
filteredValue
)
{
if
(
value
)
{
this
.
filteredValue
.
splice
(
0
,
1
,
value
);
}
else
{
this
.
filteredValue
.
splice
(
0
,
1
);
}
}
}
},
filteredValue
:
{
get
()
{
if
(
this
.
column
)
{
return
this
.
column
.
filteredValue
||
[];
}
return
[];
},
set
(
value
)
{
if
(
this
.
column
)
{
this
.
column
.
filteredValue
=
value
;
}
}
},
multiple
()
{
if
(
this
.
column
)
{
return
this
.
column
.
filterMultiple
;
}
return
true
;
}
},
mounted
()
{
this
.
popperElm
=
this
.
$el
;
this
.
referenceElm
=
this
.
cell
;
this
.
table
.
$refs
.
bodyWrapper
.
addEventListener
(
'
scroll
'
,
()
=>
{
this
.
updatePopper
();
});
this
.
$watch
(
'
showPopper
'
,
(
value
)
=>
{
if
(
this
.
column
)
this
.
column
.
filterOpened
=
value
;
if
(
value
)
{
Dropdown
.
open
(
this
);
}
else
{
Dropdown
.
close
(
this
);
}
});
}
};
</
script
>
packages/table/src/table-body.js
View file @
14495f61
import
{
getValueByPath
,
getCell
}
from
'
./util
'
;
const
getColumnById
=
function
(
table
,
columnId
)
{
let
column
=
null
;
table
.
columns
.
forEach
(
function
(
item
)
{
if
(
item
.
id
===
columnId
)
{
column
=
item
;
}
});
return
column
;
};
const
getColumnByCell
=
function
(
table
,
cell
)
{
const
matches
=
(
cell
.
className
||
''
).
match
(
/el-table_
[^\s]
+/gm
);
if
(
matches
)
{
return
getColumnById
(
table
,
matches
[
0
]);
}
return
null
;
};
import
{
getValueByPath
,
getCell
,
getColumnById
,
getColumnByCell
}
from
'
./util
'
;
export
default
{
props
:
{
...
...
packages/table/src/table-column.js
View file @
14495f61
...
...
@@ -19,21 +19,16 @@ const defaults = {
minWidth
:
48
,
realWidth
:
48
,
direction
:
''
},
filter
:
{
headerTemplate
:
function
(
h
)
{
return
<
span
>
filter
header
<
/span>; }
,
direction
:
''
}
};
const
forced
=
{
selection
:
{
headerTemplate
:
function
(
h
)
{
return
<
div
><
el
-
checkbox
return
<
el
-
checkbox
nativeOn
-
click
=
{
this
.
toggleAllSelection
}
domProps
-
value
=
{
this
.
isAllSelected
}
on
-
input
=
{
(
value
)
=>
{
this
.
$emit
(
'
allselectedchange
'
,
value
);
}
}
/
>
<
/div>
;
on
-
input
=
{
(
value
)
=>
{
this
.
$emit
(
'
allselectedchange
'
,
value
);
}
}
/>
;
},
template
:
function
(
h
,
{
row
,
column
,
store
,
$index
})
{
return
<
el
-
checkbox
...
...
@@ -47,7 +42,7 @@ const forced = {
index
:
{
// headerTemplate: function(h) { return <div>#</div>; },
headerTemplate
:
function
(
h
,
label
)
{
return
<
div
>
{
label
||
'
#
'
}
<
/div>
;
return
label
||
'
#
'
;
},
template
:
function
(
h
,
{
$index
})
{
return
<
div
>
{
$index
+
1
}
<
/div>
;
...
...
@@ -56,7 +51,7 @@ const forced = {
},
filter
:
{
headerTemplate
:
function
(
h
)
{
return
<
div
>
#
<
/div>
;
return
'
#
'
;
},
template
:
function
(
h
,
{
row
,
column
})
{
return
<
el
-
tag
type
=
"
primary
"
style
=
"
height: 16px; line-height: 16px; min-width: 40px; text-align: center
"
>
{
row
[
column
.
property
]
}
<
/el-tag>
;
...
...
@@ -118,7 +113,13 @@ export default {
fixed
:
[
Boolean
,
String
],
formatter
:
Function
,
selectable
:
Function
,
reserveSelection
:
Boolean
reserveSelection
:
Boolean
,
filterMethod
:
Function
,
filters
:
Array
,
filterMultiple
:
{
type
:
Boolean
,
default
:
true
}
},
render
()
{},
...
...
@@ -205,7 +206,13 @@ export default {
formatter
:
this
.
formatter
,
selectable
:
this
.
selectable
,
reserveSelection
:
this
.
reserveSelection
,
fixed
:
this
.
fixed
fixed
:
this
.
fixed
,
filterMethod
:
this
.
filterMethod
,
filters
:
this
.
filters
,
filterable
:
this
.
filters
||
this
.
filterMethod
,
filterMultiple
:
this
.
filterMultiple
,
filterOpened
:
false
,
filteredValue
:
[]
});
objectAssign
(
column
,
forced
[
type
]
||
{});
...
...
packages/table/src/table-header.js
View file @
14495f61
import
ElCheckbox
from
'
element-ui/packages/checkbox
'
;
import
ElTag
from
'
element-ui/packages/tag
'
;
import
Vue
from
'
vue
'
;
import
FilterPanel
from
'
./filter-panel.vue
'
;
export
default
{
name
:
'
el-table-header
'
,
...
...
@@ -31,21 +33,27 @@ export default {
on
-
mousemove
=
{
(
$event
)
=>
this
.
handleMouseMove
(
$event
,
column
)
}
on
-
mouseout
=
{
this
.
handleMouseOut
}
on
-
mousedown
=
{
(
$event
)
=>
this
.
handleMouseDown
(
$event
,
column
)
}
on
-
click
=
{
(
$event
)
=>
this
.
handleHeaderClick
(
$event
,
column
)
}
class
=
{
[
column
.
id
,
column
.
direction
,
column
.
align
,
this
.
isCellHidden
(
cellIndex
)
?
'
hidden
'
:
''
]
}
>
<
div
class
=
{
[
'
cell
'
,
column
.
filteredValue
&&
column
.
filteredValue
.
length
>
0
?
'
highlight
'
:
''
]
}
>
{
[
column
.
headerTemplate
?
column
.
headerTemplate
.
call
(
this
.
_renderProxy
,
h
,
column
.
label
)
:
<
div
>
{
column
.
label
}
<
/div>
,
:
column
.
label
}
{
column
.
sortable
?
<
div
class
=
"
caret-wrapper
"
>
?
<
span
class
=
"
caret-wrapper
"
on
-
click
=
{
(
$event
)
=>
this
.
handleHeaderClick
(
$event
,
column
)
}
>
<
i
class
=
"
sort-caret ascending
"
><
/i
>
<
i
class
=
"
sort-caret descending
"
><
/i
>
<
/div
>
<
/span
>
:
''
}
{
column
.
filterable
?
<
span
class
=
"
el-table__column-filter-trigger
"
on
-
click
=
{
(
$event
)
=>
this
.
handleFilterClick
(
$event
,
column
)
}
><
i
class
=
{
[
'
el-icon-arrow-down
'
,
column
.
filterOpened
?
'
el-icon-arrow-up
'
:
''
]
}
><
/i></
span
>
:
''
]
}
<
/div
>
<
/th
>
)
}
...
...
@@ -61,7 +69,6 @@ export default {
},
props
:
{
columns
:
{},
fixed
:
String
,
store
:
{
required
:
true
...
...
@@ -99,6 +106,19 @@ export default {
}
},
created
()
{
this
.
filterPanels
=
{};
},
beforeDestroy
()
{
const
panels
=
this
.
filterPanels
;
for
(
let
prop
in
panels
)
{
if
(
panels
.
hasOwnProperty
(
prop
)
&&
panels
[
prop
])
{
panels
[
prop
].
$destroy
(
true
);
}
}
},
methods
:
{
isCellHidden
(
index
)
{
if
(
this
.
fixed
===
true
||
this
.
fixed
===
'
left
'
)
{
...
...
@@ -114,6 +134,34 @@ export default {
this
.
store
.
commit
(
'
toggleAllSelection
'
);
},
handleFilterClick
(
event
,
column
)
{
event
.
stopPropagation
();
const
target
=
event
.
target
;
const
cell
=
target
.
parentNode
;
const
table
=
this
.
$parent
;
let
filterPanel
=
this
.
filterPanels
[
column
.
id
];
if
(
filterPanel
&&
column
.
filterOpened
)
{
filterPanel
.
showPopper
=
false
;
return
;
}
if
(
!
filterPanel
)
{
filterPanel
=
new
Vue
(
FilterPanel
);
this
.
filterPanels
[
column
.
id
]
=
filterPanel
;
filterPanel
.
table
=
table
;
filterPanel
.
cell
=
cell
;
filterPanel
.
column
=
column
;
filterPanel
.
$mount
(
document
.
createElement
(
'
div
'
));
}
setTimeout
(()
=>
{
filterPanel
.
showPopper
=
true
;
},
16
);
},
handleMouseDown
(
event
,
column
)
{
if
(
this
.
draggingColumn
&&
this
.
border
)
{
this
.
dragging
=
true
;
...
...
@@ -180,7 +228,10 @@ export default {
},
handleMouseMove
(
event
,
column
)
{
const
target
=
event
.
target
;
let
target
=
event
.
target
;
while
(
target
&&
target
.
tagName
!==
'
TH
'
)
{
target
=
target
.
parentNode
;
}
if
(
!
column
||
!
column
.
resizable
)
return
;
...
...
@@ -194,7 +245,6 @@ export default {
}
else
if
(
!
this
.
dragging
)
{
bodyStyle
.
cursor
=
''
;
this
.
draggingColumn
=
null
;
if
(
column
.
sortable
)
bodyStyle
.
cursor
=
'
pointer
'
;
}
}
},
...
...
packages/table/src/table-store.js
View file @
14495f61
import
Vue
from
'
vue
'
;
import
debounce
from
'
throttle-debounce/debounce
'
;
import
{
orderBy
}
from
'
./util
'
;
import
{
orderBy
,
getColumnById
}
from
'
./util
'
;
const
getRowIdentity
=
(
row
,
rowKey
)
=>
{
if
(
!
row
)
throw
new
Error
(
'
row is required when get row identity
'
);
...
...
@@ -24,6 +24,7 @@ const TableStore = function(table, initialState = {}) {
fixedColumns
:
[],
rightFixedColumns
:
[],
_data
:
null
,
filteredData
:
null
,
data
:
null
,
sortCondition
:
{
column
:
null
,
...
...
@@ -34,7 +35,8 @@ const TableStore = function(table, initialState = {}) {
selection
:
[],
reserveSelection
:
false
,
selectable
:
null
,
hoverRow
:
null
hoverRow
:
null
,
filters
:
{}
};
for
(
let
prop
in
initialState
)
{
...
...
@@ -80,7 +82,38 @@ TableStore.prototype.mutations = {
},
changeSortCondition
(
states
)
{
states
.
data
=
orderBy
((
states
.
_data
||
[]),
states
.
sortCondition
.
property
,
states
.
sortCondition
.
direction
);
states
.
data
=
orderBy
((
states
.
filteredData
||
states
.
_data
||
[]),
states
.
sortCondition
.
property
,
states
.
sortCondition
.
direction
);
Vue
.
nextTick
(()
=>
this
.
table
.
updateScrollY
());
},
filterChange
(
states
,
options
)
{
let
{
column
,
values
}
=
options
;
if
(
values
&&
!
Array
.
isArray
(
values
))
{
values
=
[
values
];
}
const
prop
=
column
.
property
;
if
(
prop
)
{
states
.
filters
[
column
.
id
]
=
values
;
}
let
data
=
states
.
_data
;
const
filters
=
states
.
filters
;
Object
.
keys
(
filters
).
forEach
((
columnId
)
=>
{
const
values
=
filters
[
columnId
];
if
(
!
values
||
values
.
length
===
0
)
return
;
const
column
=
getColumnById
(
this
.
states
,
columnId
);
if
(
column
&&
column
.
filterMethod
)
{
data
=
data
.
filter
((
row
)
=>
{
return
values
.
some
(
value
=>
column
.
filterMethod
.
call
(
null
,
value
,
row
));
});
}
});
states
.
filteredData
=
data
;
states
.
data
=
orderBy
(
data
,
states
.
sortCondition
.
property
,
states
.
sortCondition
.
direction
);
Vue
.
nextTick
(()
=>
this
.
table
.
updateScrollY
());
},
...
...
packages/table/src/table.vue
View file @
14495f61
...
...
@@ -91,6 +91,7 @@
import
throttle
from
'
throttle-debounce/throttle
'
;
import
debounce
from
'
throttle-debounce/debounce
'
;
import
{
addResizeListener
,
removeResizeListener
}
from
'
element-ui/src/utils/resize-event
'
;
import
{
$t
}
from
'
element-ui/src/locale
'
;
import
TableStore
from
'
./table-store
'
;
import
TableLayout
from
'
./table-layout
'
;
import
TableBody
from
'
./table-body
'
;
...
...
@@ -130,7 +131,7 @@
emptyText
:
{
type
:
String
,
default
:
'
暂无数据
'
default
:
$t
(
'
el.table.emptyText
'
)
}
},
...
...
packages/table/src/util.js
View file @
14495f61
...
...
@@ -75,3 +75,21 @@ export const orderBy = function(array, sortKey, reverse) {
return
a
===
b
?
0
:
a
>
b
?
order
:
-
order
;
});
};
export
const
getColumnById
=
function
(
table
,
columnId
)
{
let
column
=
null
;
table
.
columns
.
forEach
(
function
(
item
)
{
if
(
item
.
id
===
columnId
)
{
column
=
item
;
}
});
return
column
;
};
export
const
getColumnByCell
=
function
(
table
,
cell
)
{
const
matches
=
(
cell
.
className
||
''
).
match
(
/el-table_
[^\s]
+/gm
);
if
(
matches
)
{
return
getColumnById
(
table
,
matches
[
0
]);
}
return
null
;
};
packages/theme-default/src/index.css
View file @
14495f61
...
...
@@ -13,6 +13,7 @@
@import
"./loading.css"
;
@import
"./dialog.css"
;
@import
"./table.css"
;
@import
"./table-column.css"
;
@import
"./pagination.css"
;
@import
"./popover.css"
;
@import
"./tooltip.css"
;
...
...
packages/theme-default/src/table-column.css
View file @
14495f61
@charset
"UTF-8"
;
@import
"./checkbox.css"
;
@import
"./tag.css"
;
@import
"./common/var.css"
;
@component-namespace
el
{
@b
table-filter
{
border
:
solid
1px
#d3dce6
;
border-radius
:
2px
;
background-color
:
#fff
;
box-shadow
:
var
(
--dropdown-menu-box-shadow
);
box-sizing
:
border-box
;
margin
:
2px
0
;
/** used for dropdown mode */
@e
list
{
padding
:
5px
0
;
margin
:
0
;
list-style
:
none
;
min-width
:
100px
;
}
@e
list-item
{
line-height
:
36px
;
padding
:
0
10px
;
cursor
:
pointer
;
font-size
:
var
(
--font-size-base
);
&:hover
{
background-color
:
var
(
--dropdown-menuItem-hover-fill
);
color
:
var
(
--dropdown-menuItem-hover-color
);
}
@when
active
{
background-color
:
#20a0ff
;
color
:
#fff
;
}
}
@e
content
{
min-width
:
100px
;
}
@e
bottom
{
border-top
:
1px
solid
#d3dce6
;
padding
:
8px
;
button
{
background
:
transparent
;
border
:
none
;
color
:
#8492a6
;
cursor
:
pointer
;
font-size
:
var
(
--font-size-base
);
padding
:
0
3px
;
&:hover
{
color
:
#20a0ff
;
}
&
:focus
{
outline
:
none
;
}
&
.is-disabled
{
color
:
#c0ccda
;
cursor
:
not-allowed
;
}
}
}
@e
checkbox-group
{
padding
:
10px
;
.el-checkbox
{
display
:
block
;
margin-bottom
:
8px
;
margin-left
:
5px
;
}
.el-checkbox
:last-child
{
margin-bottom
:
0
;
}
}
}
}
\ No newline at end of file
packages/theme-default/src/table.css
View file @
14495f61
...
...
@@ -213,16 +213,21 @@
vertical-align
:
middle
;
width
:
100%
;
box-sizing
:
border-box
;
&.highlight
{
color
:
#20a0ff
;
}
}
&
div
.caret-wrapper
{
position
:
absolute
;
top
:
50%
;
transform
:
translateY
(
-50%
);
right
:
10px
;
width
:
10px
;
height
:
12px
;
padding
:
0
;
&
.caret-wrapper
{
position
:
relative
;
cursor
:
pointer
;
display
:
inline-block
;
vertical-align
:
middle
;
margin-left
:
5px
;
margin-top
:
-2px
;
width
:
16px
;
height
:
34px
;
overflow
:
initial
;
}
...
...
@@ -233,19 +238,20 @@
border
:
0
;
content
:
""
;
position
:
absolute
;
left
:
3px
;
z-index
:
2
;
&.ascending
{
top
:
0
;
top
:
11px
;
border-top
:
none
;
border-right
:
5px
solid
transparent
;
border-bottom
:
5px
solid
#99
A9BF
;
border-bottom
:
5px
solid
#99
a9bf
;
border-left
:
5px
solid
transparent
;
}
&
.descending
{
bottom
:
0
;
border-top
:
5px
solid
#99
A9BF
;
bottom
:
11px
;
border-top
:
5px
solid
#99
a9bf
;
border-right
:
5px
solid
transparent
;
border-bottom
:
none
;
border-left
:
5px
solid
transparent
;
...
...
@@ -333,7 +339,12 @@
z-index
:
-1
;
}
@e
column-filter-label
{
@e
column-filter-trigger
{
display
:
inline-block
;
line-height
:
34px
;
margin-left
:
5px
;
cursor
:
pointer
;
&
i
{
color
:
#99a9bf
;
}
...
...
src/locale/lang/en.js
View file @
14495f61
...
...
@@ -68,6 +68,12 @@ export default {
delete
:
'
Delete
'
,
preview
:
'
Preview
'
,
continue
:
'
Continue
'
},
table
:
{
emptyText
:
'
No Data
'
,
confirmFilter
:
'
Confirm
'
,
resetFilter
:
'
Reset
'
,
clearFilter
:
'
All
'
}
}
};
src/locale/lang/zh-cn.js
View file @
14495f61
...
...
@@ -68,6 +68,12 @@ export default {
delete
:
'
删除
'
,
preview
:
'
查看图片
'
,
continue
:
'
继续上传
'
},
table
:
{
emptyText
:
'
暂无数据
'
,
confirmFilter
:
'
筛选
'
,
resetFilter
:
'
重置
'
,
clearFilter
:
'
全部
'
}
}
};
test/unit/specs/table.spec.js
View file @
14495f61
...
...
@@ -54,7 +54,7 @@ describe('Table', () => {
});
it
(
'
row data
'
,
()
=>
{
const
cells
=
toArray
(
vm
.
$el
.
querySelectorAll
(
'
.cell
'
))
const
cells
=
toArray
(
vm
.
$el
.
querySelectorAll
(
'
td
.cell
'
))
.
map
(
node
=>
node
.
textContent
);
expect
(
cells
).
to
.
eql
(
testDataArr
);
...
...
@@ -591,7 +591,7 @@ describe('Table', () => {
it
(
'
ascending
'
,
done
=>
{
const
elm
=
vm
.
$el
.
querySelector
(
'
.caret-wrapper
'
);
elm
.
parentNode
.
click
();
elm
.
click
();
setTimeout
(
_
=>
{
const
lastCells
=
vm
.
$el
.
querySelectorAll
(
'
.el-table__body-wrapper tbody tr td:last-child
'
);
expect
(
toArray
(
lastCells
).
map
(
node
=>
node
.
textContent
))
...
...
@@ -603,7 +603,7 @@ describe('Table', () => {
it
(
'
descending
'
,
done
=>
{
const
elm
=
vm
.
$el
.
querySelector
(
'
.caret-wrapper
'
);
elm
.
parentNode
.
click
();
elm
.
click
();
setTimeout
(
_
=>
{
const
lastCells
=
vm
.
$el
.
querySelectorAll
(
'
.el-table__body-wrapper tbody tr td:last-child
'
);
expect
(
toArray
(
lastCells
).
map
(
node
=>
node
.
textContent
))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment