perf[Tree-Table]: organize the structure and add documentation (#1673)
This commit is contained in:
parent
f8f7667ab1
commit
fef2853951
|
@ -0,0 +1,220 @@
|
|||
|
||||
- [Enlgish](#Brief)
|
||||
|
||||
# 中文
|
||||
|
||||
## 写在前面
|
||||
|
||||
此组件仅提供一个创建 `TreeTable` 的解决思路。它基于`element-ui`的 table 组件实现,通过`el-table`的`row-style`方法,在里面判断元素是否需要隐藏或者显示,从而实现`TreeTable`的展开与收起。
|
||||
|
||||
并且本组件充分利用 `vue` 插槽的特性来方便用户自定义。
|
||||
|
||||
`evel.js` 里面,`addAttrs` 方法会给数据添加几个属性,`treeTotable` 会对数组扁平化。这些操作都不会破坏源数据,只是会新增属性。
|
||||
|
||||
## Props 说明
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
| :--------------: | :--------------------------------- | :-----: | :------: |
|
||||
| data | 原始展示数据 | Array | [] |
|
||||
| columns | 列属性 | Array | [] |
|
||||
| defaultExpandAll | 默认是否全部展开 | Boolean | false |
|
||||
| defaultChildren | 指定子树为节点对象的某个属性值 | String | children | |
|
||||
| indent | 相邻级节点间的水平缩进,单位为像素 | Number | 50 |
|
||||
|
||||
> 任何 `el-table` 的属性都支持,例如`border`、`fit`、`size`或者`@select`、`@cell-click`等方法。详情属性见`el-table`文档。
|
||||
|
||||
---
|
||||
|
||||
### 代码示例
|
||||
|
||||
```html
|
||||
<tree-table :data="data" :columns="columns" border>
|
||||
```
|
||||
|
||||
#### data(**必填**)
|
||||
|
||||
```js
|
||||
const data = [
|
||||
{
|
||||
name:'1'
|
||||
children: [
|
||||
{
|
||||
name: '1-1'
|
||||
},
|
||||
{
|
||||
name: '1-2'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: `2`
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### columns(**必填**)
|
||||
|
||||
- label: 显示在表头的文字
|
||||
- key: 对应 data 的 key。treeTable 将显示相应的 value
|
||||
- expand: `true` or `false`。若为 true,则在该列显示展开收起图标
|
||||
- checkbox: `true` or `false`。若为 true,则在该列显示`checkbox`
|
||||
- width: 每列的宽度,为一个数字(可选)。例如`200`
|
||||
- align: 对齐方式 `left/center/right`
|
||||
- header-align: 表头对齐方式 `left/center/right`
|
||||
|
||||
```javascript
|
||||
const columns = [
|
||||
{
|
||||
label: 'Checkbox',
|
||||
checkbox: true
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
key: 'id',
|
||||
expand: true
|
||||
},
|
||||
{
|
||||
label: 'Event',
|
||||
key: 'event',
|
||||
width: 200,
|
||||
align: 'left'
|
||||
},
|
||||
{
|
||||
label: 'Scope',
|
||||
key: 'scope'
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
> 树表组件将会根据 columns 的 key 属性生成具名插槽,如果你需要对列数据进行自定义,通过插槽即可实现
|
||||
|
||||
```html
|
||||
<template slot="your key" slot-scope="{scope}">
|
||||
<el-tag>level: {{ scope.row._level }}</el-tag>
|
||||
<el-tag>expand: {{ scope.row._expand }}</el-tag>
|
||||
<el-tag>select: {{ scope.row._select }}</el-tag>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
目前提供了几个方法,不过只是`beta`版本,之后很可能会修改。
|
||||
|
||||
```js
|
||||
this.$refs.TreeTable.addChild(row, data) //添加子元素
|
||||
this.$refs.TreeTable.addBrother(row, data) //添加兄弟元素
|
||||
this.$refs.TreeTable.delete(row) //删除该元素
|
||||
```
|
||||
|
||||
## 其他
|
||||
|
||||
如果有其他的需求,请参考[el-table](http://element-cn.eleme.io/#/en-US/component/table)的 api 自行修改 index.vue
|
||||
|
||||
# English
|
||||
|
||||
## Brief
|
||||
|
||||
This component only provides a solution for creating `TreeTable`. It is based on the `element-ui` table component. It uses the `row-style` method of `el-table` to determine whether the element needs to be hidden or displayed.
|
||||
|
||||
And this component makes full use of the features of the `vue` slot to make it user-friendly.
|
||||
|
||||
In `evel.js`, the `addAttrs` method adds several properties to the data, and `treeTotable` flattens the array. None of these operations will destroy the source data, just add properties.
|
||||
|
||||
## Props
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
| :--------------: | :----------------------------------------------------------- | :-----: | :------: |
|
||||
| data | original display data | Array | [] |
|
||||
| columns | column attribute | Array | [] |
|
||||
| defaultExpandAll | whether to expand all nodes by default | Boolean | false |
|
||||
| defaultChildren | specify which node object is used as the node's subtree | String | children | |
|
||||
| indent | horizontal indentation of nodes in adjacent levels in pixels | Number | 50 |
|
||||
|
||||
> Any of the `el-table` properties are supported, such as `border`, `fit`, `size` or `@select`, `@cell-click`. See the ʻel-table` documentation for details.
|
||||
|
||||
---
|
||||
|
||||
### Example
|
||||
|
||||
```html
|
||||
<tree-table :data="data" :columns="columns" border>
|
||||
```
|
||||
|
||||
#### data(**Required**)
|
||||
|
||||
```js
|
||||
const data = [
|
||||
{
|
||||
name:'1'
|
||||
children: [
|
||||
{
|
||||
name: '1-1'
|
||||
},
|
||||
{
|
||||
name: '1-2'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: `2`
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### columns(**Required**)
|
||||
|
||||
- label: text displayed in the header
|
||||
- key: data.key will show in column
|
||||
- expand: `true` or `false`
|
||||
- checkbox: `true` or `false`
|
||||
- width: column width 。such as `200`
|
||||
- align: alignment `left/center/right`
|
||||
- header-align: alignment of the table header `left/center/right`
|
||||
|
||||
```javascript
|
||||
const columns = [
|
||||
{
|
||||
label: 'Checkbox',
|
||||
checkbox: true
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
key: 'id',
|
||||
expand: true
|
||||
},
|
||||
{
|
||||
label: 'Event',
|
||||
key: 'event',
|
||||
width: 200,
|
||||
align: 'left'
|
||||
},
|
||||
{
|
||||
label: 'Scope',
|
||||
key: 'scope'
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
> The tree table component will generate a named slot based on the key property of columns. If you need to customize the column data, you can do it through the slot.
|
||||
|
||||
```html
|
||||
<template slot="your key" slot-scope="{scope}">
|
||||
<el-tag>level: {{ scope.row._level }}</el-tag>
|
||||
<el-tag>expand: {{ scope.row._expand }}</el-tag>
|
||||
<el-tag>select: {{ scope.row._select }}</el-tag>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
Several methods are currently available, but only the `beta` version, which is likely to be modified later.
|
||||
|
||||
```js
|
||||
this.$refs.TreeTable.addChild(row, data) //Add child elements
|
||||
this.$refs.TreeTable.addBrother(row, data) //Add a sibling element
|
||||
this.$refs.TreeTable.delete(row) //Delete the element
|
||||
```
|
||||
|
||||
## Other
|
||||
|
||||
If you have other requirements, please refer to the [el-table](http://element-cn.eleme.io/#/en-US/component/table) api to modify the index.vue
|
|
@ -1,99 +0,0 @@
|
|||
## 写在前面
|
||||
|
||||
此组件仅提供一个创建 TreeTable 的解决思路,本组件充分利用 vue 插槽的特性,方便用户自定义
|
||||
|
||||
evel.js 里面 `addAttrs` 方法会给数据添加几个属性,treeTotable 会对数组扁平化。这些操作都不会破坏源数据,只是会新增属性。
|
||||
|
||||
调用 addAttrs 后,因\_\_parent 属性,会造成数据循环引用,使用 JSON.stringify()报错,所以转成 JSON 之前需要清除\_\_parent 属性。
|
||||
|
||||
## prop 说明
|
||||
|
||||
- data(原始数据,要求是一个数组或者对象)
|
||||
- columns(列属性,要求是一个数组)
|
||||
- renderContent(数组扁平化方法(可选))
|
||||
- defaultExpandAll(默认是否全部展开,默认全部展开)
|
||||
- defaultChildren(子元素名,默认为 children)
|
||||
- spreadOffset(扩展符号的偏移量,默认为 50px)
|
||||
- checkboxOffset(复选框的偏移量,默认为 50px)
|
||||
|
||||
---
|
||||
|
||||
### 代码示例
|
||||
|
||||
- data(**必填**)
|
||||
|
||||
原始数据,
|
||||
|
||||
```js
|
||||
const data = [
|
||||
{
|
||||
key1: value1,
|
||||
key2: value2,
|
||||
children: [
|
||||
{
|
||||
key1: value1
|
||||
},
|
||||
{
|
||||
key1: value1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
key1: value1
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
或者
|
||||
|
||||
```javascript
|
||||
{
|
||||
key1: value1,
|
||||
key2: value2,
|
||||
children: [{
|
||||
key1: value1
|
||||
},
|
||||
{
|
||||
key1: value1
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
- columns
|
||||
|
||||
1. label: 显示在表头的文字
|
||||
2. key: 对应 data 的 key。treeTable 将显示相应的 value
|
||||
3. width: 每列的宽度,为一个数字(可选)
|
||||
|
||||
树表组件将会根据 columns 的 key 属性生成具名插槽,如果你需要对列数据进行自定义,通过插槽即可实现
|
||||
|
||||
```javascript
|
||||
const columns = [
|
||||
// 建议第一列做展开收缩操作
|
||||
{ label: '', key: '__spread', width: '200' },
|
||||
// 如果添加复选框
|
||||
{ label: '', key: '__checkbox', width: '200' },
|
||||
{
|
||||
label: string,
|
||||
key: string,
|
||||
width: number
|
||||
},
|
||||
{
|
||||
label: string,
|
||||
key: string,
|
||||
width: number
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### renderContent
|
||||
|
||||
解析函数,function,非必须
|
||||
|
||||
如果不提供,将使用默认的[evalFunc](./eval.js)
|
||||
|
||||
如果提供了 evalFunc,那么会用提供的 evalFunc 去解析 data,并返回 treeTable 渲染所需要的值。
|
||||
|
||||
## 其他
|
||||
|
||||
如果有其他的需求,请参考[el-table](http://element-cn.eleme.io/#/en-US/component/table)的 api 自行修改 index.vue
|
|
@ -0,0 +1 @@
|
|||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M44.8 0h79.543C126.78 0 128 1.422 128 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H44.8c-2.438 0-3.657-1.422-3.657-4.267V4.267C41.143 1.422 42.362 0 44.8 0zm22.857 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 80 64 78.578 64 75.733V52.267C64 49.422 65.219 48 67.657 48zm0 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 128 64 126.578 64 123.733v-23.466C64 97.422 65.219 96 67.657 96zM50.286 68.267c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V32h6.4c2.02 0 3.658-1.91 3.658-4.267V4.267C27.429 1.91 25.79 0 23.77 0H3.657C1.637 0 0 1.91 0 4.267v23.466C0 30.09 1.637 32 3.657 32h6.4v80c0 2.356 1.638 4.267 3.657 4.267h36.572c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V68.267h32.915z"/></svg>
|
After Width: | Height: | Size: 906 B |
|
@ -10,6 +10,7 @@ import Layout from '@/views/layout/Layout'
|
|||
import componentsRouter from './modules/components'
|
||||
import chartsRouter from './modules/charts'
|
||||
import tableRouter from './modules/table'
|
||||
import treeTableRouter from './modules/tree-table'
|
||||
import nestedRouter from './modules/nested'
|
||||
|
||||
/** note: sub-menu only appear when children.length>=1
|
||||
|
@ -162,6 +163,7 @@ export const asyncRouterMap = [
|
|||
chartsRouter,
|
||||
nestedRouter,
|
||||
tableRouter,
|
||||
treeTableRouter,
|
||||
|
||||
{
|
||||
path: '/example',
|
||||
|
|
|
@ -30,18 +30,6 @@ const tableRouter = {
|
|||
name: 'InlineEditTable',
|
||||
meta: { title: 'inlineEditTable' }
|
||||
},
|
||||
{
|
||||
path: 'tree-table',
|
||||
component: () => import('@/views/table/treeTable/treeTable'),
|
||||
name: 'TreeTableDemo',
|
||||
meta: { title: 'treeTable' }
|
||||
},
|
||||
{
|
||||
path: 'custom-tree-table',
|
||||
component: () => import('@/views/table/treeTable/customTreeTable'),
|
||||
name: 'CustomTreeTableDemo',
|
||||
meta: { title: 'customTreeTable' }
|
||||
},
|
||||
{
|
||||
path: 'complex-table',
|
||||
component: () => import('@/views/table/complexTable'),
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/** When your routing table is too long, you can split it into small modules**/
|
||||
|
||||
import Layout from '@/views/layout/Layout'
|
||||
|
||||
const treeTableRouter = {
|
||||
path: '/tree-table',
|
||||
component: Layout,
|
||||
redirect: '/table/complex-table',
|
||||
name: 'TreeTable',
|
||||
meta: {
|
||||
title: 'treeTable',
|
||||
icon: 'tree-table'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/tree-table/index'),
|
||||
name: 'TreeTableDemo',
|
||||
meta: { title: 'treeTable' }
|
||||
},
|
||||
{
|
||||
path: 'custom',
|
||||
component: () => import('@/views/tree-table/custom'),
|
||||
name: 'CustomTreeTableDemo',
|
||||
meta: { title: 'customTreeTable' }
|
||||
}
|
||||
]
|
||||
}
|
||||
export default treeTableRouter
|
|
@ -1,4 +1,4 @@
|
|||
export const data = [
|
||||
const data = [
|
||||
{
|
||||
name: '1',
|
||||
timeLine: 100,
|
||||
|
@ -47,3 +47,5 @@ export const data = [
|
|||
}
|
||||
]
|
||||
|
||||
export default data
|
||||
|
|
@ -1,12 +1,10 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="app-container">
|
||||
<el-tag style="margin-bottom:20px;">
|
||||
<a
|
||||
href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable"
|
||||
target="_blank"
|
||||
>Documentation</a>
|
||||
</el-tag>
|
||||
|
||||
<el-button type="primary" size="small" style="margin:0 0 20px 0;">
|
||||
<a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a>
|
||||
</el-button>
|
||||
|
||||
<tree-table
|
||||
ref="TreeTable"
|
||||
|
@ -85,9 +83,8 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import TreeTable from '@/components/TreeTable'
|
||||
import { data } from './data.js'
|
||||
import data from './data.js'
|
||||
|
||||
export default {
|
||||
components: { TreeTable },
|
||||
|
@ -145,11 +142,11 @@ export default {
|
|||
},
|
||||
addMenuItem(row, type) {
|
||||
if (type === 'children') {
|
||||
this.$refs.TreeTable.addChild(row, { name: 'child' })
|
||||
this.$refs.TreeTable.addChild(row, { name: 'child', timeLine: this.randomNum() })
|
||||
}
|
||||
|
||||
if (type === 'brother') {
|
||||
this.$refs.TreeTable.addBrother(row, { name: 'brother' })
|
||||
this.$refs.TreeTable.addBrother(row, { name: 'brother', timeLine: this.randomNum() })
|
||||
}
|
||||
},
|
||||
deleteItem(row) {
|
||||
|
@ -157,6 +154,12 @@ export default {
|
|||
},
|
||||
selectChange(val) {
|
||||
console.log(val)
|
||||
},
|
||||
randomNum() {
|
||||
// return 1~100
|
||||
const max = 100
|
||||
const min = 1
|
||||
return Math.floor(Math.random() * (max - min + 1) + min)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
|
||||
const data = [
|
||||
{
|
||||
id: 0,
|
||||
event: 'Event-0',
|
||||
timeLine: 50
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
event: 'Event-1',
|
||||
timeLine: 100,
|
||||
children: [
|
||||
{
|
||||
id: 2,
|
||||
event: 'Event-2',
|
||||
timeLine: 10
|
||||
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
event: 'Event-3',
|
||||
timeLine: 90,
|
||||
children: [
|
||||
{
|
||||
id: 4,
|
||||
event: 'Event-4',
|
||||
timeLine: 5
|
||||
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
event: 'Event-5',
|
||||
timeLine: 10
|
||||
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
event: 'Event-6',
|
||||
timeLine: 75,
|
||||
|
||||
children: [
|
||||
{
|
||||
id: 7,
|
||||
event: 'Event-7',
|
||||
timeLine: 50,
|
||||
|
||||
children: [
|
||||
{
|
||||
id: 71,
|
||||
event: 'Event-7-1',
|
||||
timeLine: 25
|
||||
|
||||
},
|
||||
{
|
||||
id: 72,
|
||||
event: 'Event-7-2',
|
||||
timeLine: 5
|
||||
|
||||
},
|
||||
{
|
||||
id: 73,
|
||||
event: 'Event-7-3',
|
||||
timeLine: 20
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
event: 'Event-8',
|
||||
timeLine: 25
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
export default data
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
<div style="margin-bottom:20px;">
|
||||
|
||||
<el-button type="primary" class="option-item">
|
||||
<el-button type="primary" size="small" class="option-item">
|
||||
<a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a>
|
||||
</el-button>
|
||||
|
||||
|
@ -42,8 +42,8 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import treeTable from '@/components/TreeTable'
|
||||
import data from './data'
|
||||
|
||||
export default {
|
||||
name: 'TreeTableDemo',
|
||||
|
@ -78,83 +78,7 @@ export default {
|
|||
key: 'operation'
|
||||
}
|
||||
],
|
||||
data: [
|
||||
{
|
||||
id: 0,
|
||||
event: 'Event-0',
|
||||
timeLine: 50
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
event: 'Event-1',
|
||||
timeLine: 100,
|
||||
children: [
|
||||
{
|
||||
id: 2,
|
||||
event: 'Event-2',
|
||||
timeLine: 10
|
||||
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
event: 'Event-3',
|
||||
timeLine: 90,
|
||||
children: [
|
||||
{
|
||||
id: 4,
|
||||
event: 'Event-4',
|
||||
timeLine: 5
|
||||
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
event: 'Event-5',
|
||||
timeLine: 10
|
||||
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
event: 'Event-6',
|
||||
timeLine: 75,
|
||||
|
||||
children: [
|
||||
{
|
||||
id: 7,
|
||||
event: 'Event-7',
|
||||
timeLine: 50,
|
||||
|
||||
children: [
|
||||
{
|
||||
id: 71,
|
||||
event: 'Event-7-1',
|
||||
timeLine: 25
|
||||
|
||||
},
|
||||
{
|
||||
id: 72,
|
||||
event: 'Event-7-2',
|
||||
timeLine: 5
|
||||
|
||||
},
|
||||
{
|
||||
id: 73,
|
||||
event: 'Event-7-3',
|
||||
timeLine: 20
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
event: 'Event-8',
|
||||
timeLine: 25
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
data: data
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -176,6 +100,20 @@ export default {
|
|||
},
|
||||
click(scope) {
|
||||
console.log(scope)
|
||||
|
||||
const row = scope.row
|
||||
const message = Object.keys(row)
|
||||
.map(i => {
|
||||
return `<p>${i}: ${row[i]}</p>`
|
||||
})
|
||||
.join('')
|
||||
|
||||
this.$notify({
|
||||
title: 'Success',
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: message,
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue