add table demo
parent
5a9b756338
commit
d7c2739c23
|
@ -4,7 +4,10 @@ import { Store } from './createStore'
|
|||
|
||||
const BodyRowProps = {
|
||||
store: Store,
|
||||
rowKey: PropTypes.string,
|
||||
rowKey: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
]),
|
||||
prefixCls: PropTypes.string,
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<template>
|
||||
<div class='editable-cell'>
|
||||
<div v-if="editable" class='editable-cell-input-wrapper'>
|
||||
<a-input
|
||||
:value="value"
|
||||
@change="handleChange"
|
||||
@pressEnter="check"
|
||||
/><a-icon
|
||||
type='check'
|
||||
class='editable-cell-icon-check'
|
||||
@click="check"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class='editable-cell-text-wrapper'>
|
||||
{{value || ' '}}
|
||||
<a-icon type='edit' class='editable-cell-icon' @click="edit" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
text: String,
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
value: this.text,
|
||||
editable: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange (e) {
|
||||
const value = e.target.value
|
||||
this.value = value
|
||||
},
|
||||
check () {
|
||||
this.editable = false
|
||||
this.$emit('change', this.value)
|
||||
},
|
||||
edit () {
|
||||
this.editable = true
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -50,6 +50,14 @@ export default {
|
|||
mounted() {
|
||||
this.fetch();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: [],
|
||||
pagination: {},
|
||||
loading: false,
|
||||
columns,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTableChange (pagination, filters, sorter) {
|
||||
console.log(pagination);
|
||||
|
@ -86,14 +94,6 @@ export default {
|
|||
});
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: [],
|
||||
pagination: {},
|
||||
loading: false,
|
||||
columns,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
<cn>
|
||||
#### 基本用法
|
||||
简单的表格,最后一列是各种操作。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### basic Usage
|
||||
Simple table with actions.
|
||||
</us>
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-table :columns="columns" :dataSource="data">
|
||||
<template slot="name" slot-scope="text">
|
||||
<a href="#">{{text}}</a>
|
||||
</template>
|
||||
<template slot="action" slot-scope="text, record">
|
||||
<span>
|
||||
<a href="#">Action 一 {{record.name}}</a>
|
||||
<a-divider type="vertical" />
|
||||
<a href="#">Delete</a>
|
||||
<a-divider type="vertical" />
|
||||
<a href="#" class="ant-dropdown-link">
|
||||
More actions <a-icon type="down" />
|
||||
</a>
|
||||
</span>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
<script>
|
||||
const columns = [{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
slotScopeName: 'name',
|
||||
}, {
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
key: 'age',
|
||||
}, {
|
||||
title: 'Address',
|
||||
dataIndex: 'address',
|
||||
key: 'address',
|
||||
}, {
|
||||
title: 'Action',
|
||||
key: 'action',
|
||||
slotScopeName: 'action',
|
||||
}];
|
||||
|
||||
const data = [{
|
||||
key: '1',
|
||||
name: 'John Brown',
|
||||
age: 32,
|
||||
address: 'New York No. 1 Lake Park',
|
||||
}, {
|
||||
key: '2',
|
||||
name: 'Jim Green',
|
||||
age: 42,
|
||||
address: 'London No. 1 Lake Park',
|
||||
}, {
|
||||
key: '3',
|
||||
name: 'Joe Black',
|
||||
age: 32,
|
||||
address: 'Sidney No. 1 Lake Park',
|
||||
}];
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
data,
|
||||
columns,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
|
@ -1,76 +0,0 @@
|
|||
<cn>
|
||||
#### 基本用法
|
||||
简单的表格,最后一列是各种操作。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### basic Usage
|
||||
Simple table with actions.
|
||||
</us>
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-table :columns="columns" :dataSource="data">
|
||||
<template slot="name" slot-scope="text">
|
||||
<a href="#">{{text}}</a>
|
||||
</template>
|
||||
<template slot="action" slot-scope="text, record">
|
||||
<span>
|
||||
<a href="#">Action 一 {{record.name}}</a>
|
||||
<a-divider type="vertical" />
|
||||
<a href="#">Delete</a>
|
||||
<a-divider type="vertical" />
|
||||
<a href="#" class="ant-dropdown-link">
|
||||
More actions <a-icon type="down" />
|
||||
</a>
|
||||
</span>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
<script>
|
||||
const columns = [{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
slotScopeName: 'name',
|
||||
}, {
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
key: 'age',
|
||||
}, {
|
||||
title: 'Address',
|
||||
dataIndex: 'address',
|
||||
key: 'address',
|
||||
}, {
|
||||
title: 'Action',
|
||||
key: 'action',
|
||||
slotScopeName: 'action',
|
||||
}];
|
||||
|
||||
const data = [{
|
||||
key: '1',
|
||||
name: 'John Brown',
|
||||
age: 32,
|
||||
address: 'New York No. 1 Lake Park',
|
||||
}, {
|
||||
key: '2',
|
||||
name: 'Jim Green',
|
||||
age: 42,
|
||||
address: 'London No. 1 Lake Park',
|
||||
}, {
|
||||
key: '3',
|
||||
name: 'Joe Black',
|
||||
age: 32,
|
||||
address: 'Sidney No. 1 Lake Park',
|
||||
}];
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
data,
|
||||
columns,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
|
@ -35,10 +35,10 @@ Table cell supports `colSpan` and `rowSpan` that set in render return object. Wh
|
|||
const renderContent = (value, row, index) => {
|
||||
const obj = {
|
||||
children: value,
|
||||
props: {},
|
||||
attrs: {},
|
||||
};
|
||||
if (index === 4) {
|
||||
obj.props.colSpan = 0;
|
||||
obj.attrs.colSpan = 0;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
@ -93,7 +93,7 @@ export default {
|
|||
}
|
||||
return {
|
||||
children: <a href="#">{text}</a>,
|
||||
props: {
|
||||
attrs: {
|
||||
colSpan: 5,
|
||||
},
|
||||
};
|
||||
|
@ -101,7 +101,7 @@ export default {
|
|||
}, {
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
render: renderContent,
|
||||
customRender: renderContent,
|
||||
}, {
|
||||
title: 'Home phone',
|
||||
colSpan: 2,
|
||||
|
@ -109,17 +109,17 @@ export default {
|
|||
customRender: (value, row, index) => {
|
||||
const obj = {
|
||||
children: value,
|
||||
props: {},
|
||||
attrs: {},
|
||||
};
|
||||
if (index === 2) {
|
||||
obj.props.rowSpan = 2;
|
||||
obj.attrs.rowSpan = 2;
|
||||
}
|
||||
// These two are merged into above cell
|
||||
if (index === 3) {
|
||||
obj.props.rowSpan = 0;
|
||||
obj.attrs.rowSpan = 0;
|
||||
}
|
||||
if (index === 4) {
|
||||
obj.props.colSpan = 0;
|
||||
obj.attrs.colSpan = 0;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
@ -127,11 +127,11 @@ export default {
|
|||
title: 'Phone',
|
||||
colSpan: 0,
|
||||
dataIndex: 'phone',
|
||||
render: renderContent,
|
||||
customRender: renderContent,
|
||||
}, {
|
||||
title: 'Address',
|
||||
dataIndex: 'address',
|
||||
render: renderContent,
|
||||
customRender: renderContent,
|
||||
}];
|
||||
return {
|
||||
data,
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
<cn>
|
||||
#### 自定义筛选菜单
|
||||
通过 `filterDropdown`、`filterDropdownVisible` 和 `filterDropdownVisibleChange` 定义自定义的列筛选功能,并实现一个搜索列的示例。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Customized filter panel
|
||||
Implement a customized column search example via `filterDropdown`, `filterDropdownVisible` and `filterDropdownVisibleChange`.
|
||||
</us>
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-table :dataSource="data">
|
||||
<a-table-column
|
||||
title="Name"
|
||||
dataIndex="name"
|
||||
key="name"
|
||||
:filterDropdownVisible="filterDropdownVisible"
|
||||
@filterDropdownVisibleChange="onFilterDropdownVisibleChange"
|
||||
>
|
||||
<div slot="filterDropdown" class="custom-filter-dropdown">
|
||||
<a-input
|
||||
ref="searchInput"
|
||||
placeholder="Search name"
|
||||
:value="searchText"
|
||||
@change="onInputChange"
|
||||
@pressEnter="onSearch"
|
||||
/>
|
||||
<a-button type="primary" @click="onSearch">Search</a-button>
|
||||
</div>
|
||||
<a-icon slot="filterIcon" type="smile-o" :style="{ color: this.filtered ? '#108ee9' : '#aaa' }" />
|
||||
</a-table-column>
|
||||
<a-table-column
|
||||
title="Age"
|
||||
dataIndex="age"
|
||||
key="age"
|
||||
/>
|
||||
<a-table-column
|
||||
title="Address"
|
||||
dataIndex="address"
|
||||
key="address"
|
||||
:filters="filters"
|
||||
@filter="(value, record) => record.address.indexOf(value) === 0"
|
||||
/>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const data = [{
|
||||
key: '1',
|
||||
name: 'John Brown',
|
||||
age: 32,
|
||||
address: 'New York No. 1 Lake Park',
|
||||
}, {
|
||||
key: '2',
|
||||
name: 'Joe Black',
|
||||
age: 42,
|
||||
address: 'London No. 1 Lake Park',
|
||||
}, {
|
||||
key: '3',
|
||||
name: 'Jim Green',
|
||||
age: 32,
|
||||
address: 'Sidney No. 1 Lake Park',
|
||||
}, {
|
||||
key: '4',
|
||||
name: 'Jim Red',
|
||||
age: 32,
|
||||
address: 'London No. 2 Lake Park',
|
||||
}];
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
filterDropdownVisible: false,
|
||||
data,
|
||||
searchText: '',
|
||||
filtered: false,
|
||||
filters: [{
|
||||
text: 'London',
|
||||
value: 'London',
|
||||
}, {
|
||||
text: 'New York',
|
||||
value: 'New York',
|
||||
}],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onFilterDropdownVisibleChange(visible) {
|
||||
this.filterDropdownVisible = visible;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.searchInput && this.$refs.searchInput.focus()
|
||||
})
|
||||
},
|
||||
onInputChange(e) {
|
||||
this.searchText = e.target.value;
|
||||
},
|
||||
onSearch () {
|
||||
const { searchText } = this;
|
||||
const reg = new RegExp(searchText, 'gi');
|
||||
Object.assign(this, {
|
||||
filterDropdownVisible: false,
|
||||
filtered: !!searchText,
|
||||
data: data.map((record) => {
|
||||
const match = record.name.match(reg);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
...record,
|
||||
name: (
|
||||
<span>
|
||||
{record.name.split(reg).map((text, i) => (
|
||||
i > 0 ? [<span class="highlight">{match[0]}</span>, text] : text
|
||||
))}
|
||||
</span>
|
||||
),
|
||||
};
|
||||
}).filter(record => !!record),
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.custom-filter-dropdown {
|
||||
padding: 8px;
|
||||
border-radius: 6px;
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 6px rgba(0, 0, 0, .2);
|
||||
}
|
||||
|
||||
.custom-filter-dropdown input {
|
||||
width: 130px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: #f50;
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -0,0 +1,145 @@
|
|||
<cn>
|
||||
#### 可编辑单元格
|
||||
带单元格编辑功能的表格。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Editable Cells
|
||||
Table with editable cells.
|
||||
</us>
|
||||
|
||||
```html
|
||||
<template>
|
||||
<div>
|
||||
<a-button class="editable-add-btn" @click="handleAdd">Add</a-button>
|
||||
<a-table bordered :dataSource="dataSource" :columns="columns">
|
||||
<template slot="name" slot-scope="text, record">
|
||||
<EditableCell :text="text" @change="onCellChange(record.key, 'name')"/>
|
||||
</template>
|
||||
<template slot="operation" slot-scope="text, record">
|
||||
<a-popconfirm
|
||||
v-if="dataSource.length"
|
||||
title="Sure to delete?"
|
||||
@confirm="() => onDelete(record.key)">
|
||||
<a href="#">Delete</a>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import EditableCell from './EditableCell'
|
||||
/*
|
||||
* EditableCell Code https://github.com/vueComponent/ant-design/blob/master/components/table/demo/EditableCell.vue
|
||||
*/
|
||||
export default {
|
||||
components: {
|
||||
EditableCell,
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
dataSource: [{
|
||||
key: '0',
|
||||
name: 'Edward King 0',
|
||||
age: '32',
|
||||
address: 'London, Park Lane no. 0',
|
||||
}, {
|
||||
key: '1',
|
||||
name: 'Edward King 1',
|
||||
age: '32',
|
||||
address: 'London, Park Lane no. 1',
|
||||
}],
|
||||
count: 2,
|
||||
columns: [{
|
||||
title: 'name',
|
||||
dataIndex: 'name',
|
||||
width: '30%',
|
||||
slotScopeName: 'name',
|
||||
}, {
|
||||
title: 'age',
|
||||
dataIndex: 'age',
|
||||
}, {
|
||||
title: 'address',
|
||||
dataIndex: 'address',
|
||||
}, {
|
||||
title: 'operation',
|
||||
dataIndex: 'operation',
|
||||
slotScopeName: 'operation',
|
||||
}],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onCellChange (key, dataIndex) {
|
||||
return (value) => {
|
||||
const dataSource = [...this.dataSource]
|
||||
const target = dataSource.find(item => item.key === key)
|
||||
if (target) {
|
||||
target[dataIndex] = value
|
||||
this.dataSource = dataSource
|
||||
}
|
||||
}
|
||||
},
|
||||
onDelete (key) {
|
||||
const dataSource = [...this.dataSource]
|
||||
this.dataSource = dataSource.filter(item => item.key !== key)
|
||||
},
|
||||
handleAdd () {
|
||||
const { count, dataSource } = this
|
||||
const newData = {
|
||||
key: count,
|
||||
name: `Edward King ${count}`,
|
||||
age: 32,
|
||||
address: `London, Park Lane no. ${count}`,
|
||||
}
|
||||
this.dataSource = [...dataSource, newData]
|
||||
this.count = count + 1
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.editable-cell {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editable-cell-input-wrapper,
|
||||
.editable-cell-text-wrapper {
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
.editable-cell-text-wrapper {
|
||||
padding: 5px 24px 5px 5px;
|
||||
}
|
||||
|
||||
.editable-cell-icon,
|
||||
.editable-cell-icon-check {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.editable-cell-icon {
|
||||
line-height: 18px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.editable-cell-icon-check {
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.editable-cell:hover .editable-cell-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.editable-cell-icon:hover,
|
||||
.editable-cell-icon-check:hover {
|
||||
color: #108ee9;
|
||||
}
|
||||
|
||||
.editable-add-btn {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
|
@ -162,8 +162,10 @@ export default {
|
|||
const dropdownSelectedClass = this.selectedKeys.length > 0 ? `${prefixCls}-selected` : ''
|
||||
|
||||
return filterIcon ? cloneElement(filterIcon, {
|
||||
title: locale.filterTitle,
|
||||
className: classNames(filterIcon.className, {
|
||||
attrs: {
|
||||
title: locale.filterTitle,
|
||||
},
|
||||
class: classNames(filterIcon.className, {
|
||||
[`${prefixCls}-icon`]: true,
|
||||
}),
|
||||
}) : <Icon title={locale.filterTitle} type='filter' class={dropdownSelectedClass} />
|
||||
|
|
|
@ -23,11 +23,11 @@ const Table = {
|
|||
const events = getEvents(element)
|
||||
const listeners = {}
|
||||
Object.keys(events).forEach(e => {
|
||||
const k = `on_${e}`
|
||||
const k = `on-${e}`
|
||||
listeners[camelize(k)] = events[e]
|
||||
})
|
||||
const { default: children, title } = getSlots(element)
|
||||
const column = { title, ...props, style, class: cls, ...listeners }
|
||||
const { default: children, ...restSlots } = getSlots(element)
|
||||
const column = { ...restSlots, ...props, style, class: cls, ...listeners }
|
||||
if (key) {
|
||||
column.key = key
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ export const SelectionBoxProps = {
|
|||
export const FilterMenuProps = {
|
||||
locale: TableLocale,
|
||||
selectedKeys: PropTypes.arrayOf(PropTypes.string),
|
||||
column: PropTypes.shape(ColumnProps),
|
||||
column: PropTypes.object,
|
||||
confirmFilter: PropTypes.func,
|
||||
prefixCls: PropTypes.string,
|
||||
dropdownPrefixCls: PropTypes.string,
|
||||
|
|
|
@ -23,7 +23,7 @@ const Table = {
|
|||
const events = getEvents(element)
|
||||
const listeners = {}
|
||||
Object.keys(events).forEach(e => {
|
||||
const k = `on_${e}`
|
||||
const k = `on-${e}`
|
||||
listeners[camelize(k)] = events[e]
|
||||
})
|
||||
const { default: children, title } = getSlots(element)
|
||||
|
|
|
@ -66,7 +66,8 @@ export default {
|
|||
if (customRender) {
|
||||
text = customRender(text, record, index)
|
||||
if (this.isInvalidRenderCellText(text)) {
|
||||
tdProps.attrs = text.attrs || text.props || {}
|
||||
tdProps.attrs = text.attrs || {}
|
||||
tdProps.props = text.props || {}
|
||||
colSpan = tdProps.attrs.colSpan
|
||||
rowSpan = tdProps.attrs.rowSpan
|
||||
text = text.children
|
||||
|
@ -93,7 +94,6 @@ export default {
|
|||
if (rowSpan === 0 || colSpan === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (column.align) {
|
||||
tdProps.style = { textAlign: column.align }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue