perf[Tree-Table]: refactor tree-table (#1587)

This commit is contained in:
liugq 2019-03-07 11:34:23 +08:00 committed by 花裤衩
parent fc9e7249e7
commit dc6030bce6
8 changed files with 551 additions and 386 deletions

View File

@ -1,29 +1,48 @@
/**
* @Author: jianglei
* @Date: 2017-10-12 12:06:49
*/
'use strict'
import Vue from 'vue' import Vue from 'vue'
export default function treeToArray(data, expandAll, parent = null, level = null) {
// Flattened array
export default function treeToArray(data, children = 'children') {
let tmp = [] let tmp = []
Array.from(data).forEach(function(record) { data.forEach((item, index) => {
if (record._expanded === undefined) { Vue.set(item, '_index', index)
Vue.set(record, '_expanded', expandAll) tmp.push(item)
} if (item[children] && item[children].length > 0) {
let _level = 1 const res = treeToArray(item[children], children)
if (level !== undefined && level !== null) { tmp = tmp.concat(res)
_level = level + 1
}
Vue.set(record, '_level', _level)
// 如果有父元素
if (parent) {
Vue.set(record, 'parent', parent)
}
tmp.push(record)
if (record.children && record.children.length > 0) {
const children = treeToArray(record.children, expandAll, record, _level)
tmp = tmp.concat(children)
} }
}) })
return tmp return tmp
} }
export function addAttrs(data, { parent = null, preIndex = false, level = 0, expand = false, children = 'children', show = true, select = false } = {}) {
data.forEach((item, index) => {
const _id = (preIndex ? `${preIndex}-${index}` : index) + ''
Vue.set(item, '_id', _id)
Vue.set(item, '_level', level)
Vue.set(item, '_expand', expand)
Vue.set(item, '_parent', parent)
Vue.set(item, '_show', show)
Vue.set(item, '_select', select)
if (item[children] && item[children].length > 0) {
addAttrs(item[children], {
parent: item,
level: level + 1,
expand,
preIndex: _id,
children,
status,
select
})
}
})
}
export function cleanParentAttr(data, children = 'children') {
data.forEach(item => {
item._parent = null
if (item[children] && item[children].length > 0) {
addAttrs(item[children], children)
}
})
return data
}

View File

@ -1,127 +1,177 @@
<template> <template>
<el-table :data="formatData" :row-style="showRow" v-bind="$attrs"> <el-table :data="tableData" :row-style="showRow" v-bind="$attrs" v-on="$listeners" >
<el-table-column v-if="columns.length===0" width="150"> <slot name="selection" />
<slot name="pre-column" />
<el-table-column
v-for="item in columns"
:label="item.label"
:key="item.key"
:width="item.width"
:align="item.align||'center'"
:header-align="item.headerAlign">
<template slot-scope="scope"> <template slot-scope="scope">
<span v-for="space in scope.row._level" :key="space" class="ms-tree-space"/> <slot :scope="scope" :name="item.key">
<span v-if="iconShow(0,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)"> <template v-if="item.expand">
<i v-if="!scope.row._expanded" class="el-icon-plus"/> <span :style="{'padding-left':+scope.row._level*indent + 'px'} "/>
<i v-else class="el-icon-minus"/> <span v-show="showSperadIcon(scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">
</span> <i v-if="!scope.row._expand" class="el-icon-plus" />
{{ scope.$index }} <i v-else class="el-icon-minus" />
</span>
</template>
<template v-if="item.checkbox">
<el-checkbox
v-if="scope.row[defaultChildren]&&scope.row[defaultChildren].length>0"
:style="{'padding-left':+scope.row._level*indent + 'px'} "
:indeterminate="scope.row._select"
v-model="scope.row._select"
@change="handleCheckAllChange(scope.row)" />
<el-checkbox
v-else
:style="{'padding-left':+scope.row._level*indent + 'px'} "
v-model="scope.row._select"
@change="handleCheckAllChange(scope.row)" />
</template>
{{ scope.row[item.key] }}
</slot>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-for="(column, index) in columns" v-else :key="column.value" :label="column.text" :width="column.width">
<template slot-scope="scope">
<!-- Todo -->
<!-- eslint-disable-next-line vue/no-confusing-v-for-v-if -->
<span v-for="space in scope.row._level" v-if="index === 0" :key="space" class="ms-tree-space"/>
<span v-if="iconShow(index,scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">
<i v-if="!scope.row._expanded" class="el-icon-plus"/>
<i v-else class="el-icon-minus"/>
</span>
{{ scope.row[column.value] }}
</template>
</el-table-column>
<slot/>
</el-table> </el-table>
</template> </template>
<script> <script>
/** import treeToArray, { addAttrs } from './eval.js'
Auth: Lei.j1ang
Created: 2018/1/19-13:59
*/
import treeToArray from './eval'
export default { export default {
name: 'TreeTable', name: 'TreeTable',
props: { props: {
/* eslint-disable */
data: { data: {
type: [Array, Object], type: Array,
required: true required: true,
default: () => []
}, },
columns: { columns: {
type: Array, type: Array,
default: () => [] default: () => []
}, },
evalFunc: Function, defaultExpandAll: {
evalArgs: Array,
expandAll: {
type: Boolean, type: Boolean,
default: false default: false
},
defaultChildren: {
type: String,
default: 'children'
},
indent: {
type: Number,
default: 50
}
},
data() {
return {
guard: 1
} }
}, },
computed: { computed: {
// children() {
formatData: function() { return this.defaultChildren
let tmp },
if (!Array.isArray(this.data)) { tableData() {
tmp = [this.data] const data = this.data
} else { if (this.data.length === 0) {
tmp = this.data return []
} }
const func = this.evalFunc || treeToArray addAttrs(data, {
const args = this.evalArgs ? Array.concat([tmp, this.expandAll], this.evalArgs) : [tmp, this.expandAll] expand: this.defaultExpandAll,
return func.apply(null, args) children: this.defaultChildren
})
const retval = treeToArray(data, this.defaultChildren)
return retval
} }
}, },
methods: { methods: {
showRow: function(row) { addBrother(row, data) {
const show = (row.row.parent ? (row.row.parent._expanded && row.row.parent._show) : true) if (row._parent) {
row.row._show = show row._parent.children.push(data)
return show ? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;' : 'display:none;' } else {
this.data.push(data)
}
}, },
// addChild(row, data) {
toggleExpanded: function(trIndex) { if (!row.children) {
const record = this.formatData[trIndex] this.$set(row, 'children', [])
record._expanded = !record._expanded }
row.children.push(data)
}, },
// delete(row) {
iconShow(index, record) { const { _index, _parent } = row
return (index === 0 && record.children && record.children.length > 0) if (_parent) {
_parent.children.splice(_index, 1)
} else {
this.data.splice(_index, 1)
}
},
getData() {
return this.tableData
},
showRow: function({ row }) {
const parent = row._parent
const show = parent ? parent._expand && parent._show : true
row._show = show
return show
? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;'
: 'display:none;'
},
showSperadIcon(record) {
return record[this.children] && record[this.children].length > 0
},
toggleExpanded(trIndex) {
const record = this.tableData[trIndex]
const expand = !record._expand
record._expand = expand
},
handleCheckAllChange(row) {
this.selcetRecursion(row, row._select, this.defaultChildren)
this.isIndeterminate = row._select
},
selcetRecursion(row, select, children = 'children') {
if (select) {
this.$set(row, '_expand', true)
this.$set(row, '_show', true)
}
const sub_item = row[children]
if (sub_item && sub_item.length > 0) {
sub_item.map(child => {
child._select = select
this.selcetRecursion(child, select, children)
})
}
} }
} }
} }
</script> </script>
<style rel="stylesheet/css">
@keyframes treeTableShow {
from {opacity: 0;}
to {opacity: 1;}
}
@-webkit-keyframes treeTableShow {
from {opacity: 0;}
to {opacity: 1;}
}
</style>
<style lang="scss" rel="stylesheet/scss" scoped> <style>
$color-blue: #2196F3; @keyframes treeTableShow {
$space-width: 18px; from {
.ms-tree-space { opacity: 0;
position: relative;
top: 1px;
display: inline-block;
font-style: normal;
font-weight: 400;
line-height: 1;
width: $space-width;
height: 14px;
&::before {
content: ""
}
} }
.processContainer{ to {
width: 100%; opacity: 1;
height: 100%;
} }
table td { }
line-height: 26px; @-webkit-keyframes treeTableShow {
from {
opacity: 0;
} }
to {
opacity: 1;
}
}
.tree-ctrl{ .tree-ctrl {
position: relative; position: relative;
cursor: pointer; cursor: pointer;
color: $color-blue; color: #2196f3;
margin-left: -$space-width; }
}
</style> </style>

View File

@ -1,89 +1,99 @@
## 写在前面 ## 写在前面
此组件仅提供一个创建TreeTable的解决思路
## prop说明 此组件仅提供一个创建 TreeTable 的解决思路,本组件充分利用 vue 插槽的特性,方便用户自定义
#### *data*
**必填**
原始数据,要求是一个数组或者对象 evel.js 里面 `addAttrs` 方法会给数据添加几个属性treeTotable 会对数组扁平化。这些操作都不会破坏源数据,只是会新增属性。
```javascript
[{ 调用 addAttrs 后,因\_\_parent 属性,会造成数据循环引用,使用 JSON.stringify()报错,所以转成 JSON 之前需要清除\_\_parent 属性。
key1: value1,
key2: value2, ## prop 说明
children: [{
- 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 key1: value1
}] }
}, ]
{ },
key1: value1 {
}] key1: value1
``` }
或者 ]
```javascript ```
{
key1: value1,
key2: value2,
children: [{
key1: value1
},
{
key1: value1
}]
}
```
#### columns 或者
列属性,要求是一个数组
1. text: 显示在表头的文字 ```javascript
2. value: 对应data的key。treeTable将显示相应的value {
3. width: 每列的宽度,为一个数字(可选) key1: value1,
key2: value2,
children: [{
key1: value1
},
{
key1: value1
}]
}
```
如果你想要每个字段都有自定义的样式或者嵌套其他组件columns可不提供直接像在el-table一样写即可如果没有自定义内容提供columns将更加的便捷方便 - columns
如果你有几个字段是需要自定义的几个不需要那么可以将不需要自定义的字段放入columns将需要自定义的内容放入到slot中详情见后文 1. label: 显示在表头的文字
```javascript 2. key: 对应 data 的 key。treeTable 将显示相应的 value
[{ 3. width: 每列的宽度,为一个数字(可选)
value:string,
text:string,
width:number
},{
value:string,
text:string,
width:number
}]
```
#### expandAll 树表组件将会根据 columns 的 key 属性生成具名插槽,如果你需要对列数据进行自定义,通过插槽即可实现
是否默认全部展开boolean值默认为false
#### evalFunc ```javascript
解析函数function非必须 const columns = [
// 建议第一列做展开收缩操作
{ label: '', key: '__spread', width: '200' },
// 如果添加复选框
{ label: '', key: '__checkbox', width: '200' },
{
label: string,
key: string,
width: number
},
{
label: string,
key: string,
width: number
}
]
```
如果不提供,将使用默认的[evalFunc](./eval.js) #### renderContent
如果提供了evalFunc,那么会用提供的evalFunc去解析data并返回treeTable渲染所需要的值。如何编写一个evalFunc请参考[*eval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/components/TreeTable/eval.js)或[*customEval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customEval.js) 解析函数function非必须
#### evalArgs 如果不提供,将使用默认的[evalFunc](./eval.js)
解析函数的参数,是一个数组
**请注意自定义的解析函数参数第一个为this.data第二个参数为 this.expandAll,你不需要在evalArgs填写。一定记住这两个参数是强制性的并且位置不可颠倒** *this.data为需要解析的数据this.expandAll为是否默认展开* 如果提供了 evalFunc,那么会用提供的 evalFunc 去解析 data并返回 treeTable 渲染所需要的值。
如你的解析函数需要的参数为`(this.data, this.expandAll,1,2,3,4)`,那么你只需要将`[1,2,3,4]`赋值给`evalArgs`就可以了 ## 其他
如果你的解析函数参数只有`(this.data, this.expandAll)`,那么就可以不用填写evalArgs了 如果有其他的需求,请参考[el-table](http://element-cn.eleme.io/#/en-US/component/table)的 api 自行修改 index.vue
具体可参考[*customEval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customEval.js)的函数参数和[customTreeTable](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customTreeTable.vue)的`evalArgs`属性值
## slot
这是一个自定义列的插槽。
默认情况下treeTable只有一行行展示数据的功能。但是一般情况下我们会要给行加上一个操作按钮或者根据当行数据展示不同的样式这时我们就需要自定义列了。请参考[customTreeTable](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customTreeTable.vue)[实例效果](https://panjiachen.github.io/vue-element-admin/#/table/tree-table)
`slot`和`columns属性`可同时存在,columns里面的数据列会在slot自定义列的左边展示
## 其他
如果有其他的需求,请参考[el-table](http://element-cn.eleme.io/#/en-US/component/table)的api自行修改index.vue

0
src/mock/table.js Normal file
View File

View File

@ -1,48 +0,0 @@
/**
* @Author: jianglei
* @Date: 2017-10-12 12:06:49
*/
'use strict'
import Vue from 'vue'
export default function treeToArray(data, expandAll, parent, level, item) {
const marLTemp = []
let tmp = []
Array.from(data).forEach(function(record) {
if (record._expanded === undefined) {
Vue.set(record, '_expanded', expandAll)
}
let _level = 1
if (level !== undefined && level !== null) {
_level = level + 1
}
Vue.set(record, '_level', _level)
// 如果有父元素
if (parent) {
Vue.set(record, 'parent', parent)
// 如果父元素有偏移量需要计算在this的偏移量中
// 偏移量还与前面同级元素有关,需要加上前面所有元素的长度和
if (!marLTemp[_level]) {
marLTemp[_level] = 0
}
Vue.set(record, '_marginLeft', marLTemp[_level] + parent._marginLeft)
Vue.set(record, '_width', record[item] / parent[item] * parent._width)
// 在本次计算过偏移量后加上自己长度,以供下一个元素使用
marLTemp[_level] += record._width
} else {
// 如果为根
// 初始化偏移量存储map
marLTemp[record.id] = []
// map中是一个数组存储的是每级的长度和
// 初始情况下为0
marLTemp[record.id][_level] = 0
Vue.set(record, '_marginLeft', 0)
Vue.set(record, '_width', 1)
}
tmp.push(record)
if (record.children && record.children.length > 0) {
const children = treeToArray(record.children, expandAll, record, _level, item)
tmp = tmp.concat(children)
}
})
return tmp
}

View File

@ -1,137 +1,162 @@
<template> <template>
<div class="app-container"> <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-tag style="margin-bottom:20px;"> <tree-table
<a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a> ref="TreeTable"
</el-tag> :data="tableData"
:default-expand-all="true"
:columns="columns"
border
default-children="children"
@selection-change ="selectChange"
>
<tree-table :data="data" :eval-func="func" :eval-args="args" :expand-all="expandAll" border> <template slot="selection">
<el-table-column label="事件"> <el-table-column type="selection" align="center" width="55"/>
<template slot-scope="scope">
<span style="color:sandybrown">{{ scope.row.event }}</span>
<el-tag>{{ scope.row.timeLine+'ms' }}</el-tag>
</template> </template>
</el-table-column>
<el-table-column label="时间线"> <template slot="pre-column">
<template slot-scope="scope"> <el-table-column type="expand" width="55">
<template>
<el-tag type="info">
Here is just a placeholder slot, you can display anything.
</el-tag>
</template>
</el-table-column>
</template>
<template slot="timeline" slot-scope="{scope}">
<el-tooltip :content="scope.row.timeLine+'ms'" effect="dark" placement="left"> <el-tooltip :content="scope.row.timeLine+'ms'" effect="dark" placement="left">
<div class="processContainer"> <div class="processContainer">
<div <div
:style="{ width:scope.row._width * 500+'px', :style="{ width:(scope.row.timeLine||0) * 3+'px',
background:scope.row._width>0.5?'rgba(233,0,0,.5)':'rgba(0,0,233,0.5)', background:scope.row.timeLine>50?'rgba(233,0,0,.5)':'rgba(0,0,233,0.5)',
marginLeft:scope.row._marginLeft * 500+'px' }" marginLeft:scope.row._level * 50+'px' }"
class="process"> class="process">
<span style="display:inline-block"/> <span style="display:inline-block"/>
</div> </div>
</div> </div>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column>
<el-table-column label="操作" width="200"> <template slot="append" slot-scope="{scope}">
<template slot-scope="scope"> <el-button
<el-button type="text" @click="message(scope.row)">点击</el-button> size="mini"
type="primary"
@click="addMenuItem(scope.row,'brother')"
>Append Brother
</el-button>
<el-button
size="mini"
type="primary"
@click="addMenuItem(scope.row,'children')"
>Append Child
</el-button>
</template> </template>
</el-table-column> <template slot="operation" slot-scope="{scope}">
</tree-table> <el-button size="mini" type="success" @click="editItem(scope.row)">Edit</el-button>
<el-button size="mini" type="danger" @click="deleteItem(scope.row)">Delete</el-button>
</template>
</tree-table>
</div>
<el-dialog :visible.sync="dialogFormVisible" title="Edit">
<el-form :model="tempItem" label-width="100px" style="width:600px">
<el-form-item label="Name">
<el-input v-model.trim="tempItem.name" placeholder="Name"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">Cancel</el-button>
<el-button type="primary" @click="updateItem">Confirm</el-button>
</span>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
/**
Auth: Lei.j1ang import TreeTable from '@/components/TreeTable'
Created: 2018/1/19-14:54 import { data } from './data.js'
*/
import treeTable from '@/components/TreeTable'
import treeToArray from './customEval'
export default { export default {
name: 'CustomTreeTableDemo', components: { TreeTable },
components: { treeTable },
data() { data() {
return { return {
func: treeToArray, tableData: [],
expandAll: false, tempItem: {},
data: dialogFormVisible: false,
columns: [
{ {
id: 1, label: 'Name',
event: '事件1', key: 'name',
timeLine: 100, expand: true
comment: '无',
children: [
{
id: 2,
event: '事件2',
timeLine: 10,
comment: '无'
},
{
id: 3,
event: '事件3',
timeLine: 90,
comment: '无',
children: [
{
id: 4,
event: '事件4',
timeLine: 5,
comment: '无'
},
{
id: 5,
event: '事件5',
timeLine: 10,
comment: '无'
},
{
id: 6,
event: '事件6',
timeLine: 75,
comment: '无',
children: [
{
id: 7,
event: '事件7',
timeLine: 50,
comment: '无',
children: [
{
id: 71,
event: '事件71',
timeLine: 25,
comment: 'xx'
},
{
id: 72,
event: '事件72',
timeLine: 5,
comment: 'xx'
},
{
id: 73,
event: '事件73',
timeLine: 20,
comment: 'xx'
}
]
},
{
id: 8,
event: '事件8',
timeLine: 25,
comment: '无'
}
]
}
]
}
]
}, },
args: [null, null, 'timeLine'] {
label: 'Timeline',
key: 'timeline'
},
{
label: 'Append',
key: 'append',
width: 300
},
{
label: 'Operation',
key: 'operation',
width: 160
}
]
} }
}, },
created() {
this.getData()
},
methods: { methods: {
message(row) { getData() {
this.$message.info(row.event) this.tableData = data
},
editItem(row) {
this.tempItem = Object.assign({}, row)
this.dialogFormVisible = true
},
updateItem() {
const data = this.$refs.TreeTable.getData()
const { _id } = this.tempItem
for (let i = 0; i < data.length; i++) {
if (data[i]._id === _id) {
data.splice(i, 1, Object.assign({}, this.tempItem))
break
}
}
this.dialogFormVisible = false
},
addMenuItem(row, type) {
if (type === 'children') {
this.$refs.TreeTable.addChild(row, { name: 'child' })
}
if (type === 'brother') {
this.$refs.TreeTable.addBrother(row, { name: 'brother' })
}
},
deleteItem(row) {
this.$refs.TreeTable.delete(row)
},
selectChange(val) {
console.log(val)
} }
} }
} }

View File

@ -0,0 +1,49 @@
export const data = [
{
name: '1',
timeLine: 100,
children: [
{
name: '1-1',
timeLine: 20
},
{
name: '1-2',
timeLine: 60,
children: [
{
name: '1-2-1',
timeLine: 35
},
{
name: '1-2-2',
timeLine: 25
}
]
}
]
},
{
name: '2',
timeLine: 80,
children: [
{
name: '2-1',
timeLine: 30
},
{
name: '2-2',
timeLine: 50
},
{
name: '2-3',
timeLine: 60
}
]
},
{
name: '3',
timeLine: 40
}
]

View File

@ -1,20 +1,48 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-tag style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
<a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a>
</el-tag>
<tree-table :data="data" :columns="columns" border/> <el-button type="primary" class="option-item">
<a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a>
</el-button>
<div class="option-item">
<el-tag>Expand All</el-tag>
<el-switch
v-model="defaultExpandAll"
active-color="#13ce66"
inactive-color="#ff4949"
@change="reset"/>
</div>
<div class="option-item">
<el-tag>Show Checkbox</el-tag>
<el-switch
v-model="showCheckbox"
active-color="#13ce66"
inactive-color="#ff4949"
/>
</div>
</div>
<tree-table :key="key" :default-expand-all="defaultExpandAll" :data="data" :columns="columns" border>
<template slot="scope" 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>
<template slot="operation" slot-scope="{scope}">
<el-button type="primary" size="" @click="click(scope)">Click</el-button>
</template>
</tree-table>
</div> </div>
</template> </template>
<script> <script>
/**
Auth: Lei.j1ang
Created: 2018/1/19-14:54
*/
import treeTable from '@/components/TreeTable' import treeTable from '@/components/TreeTable'
export default { export default {
@ -22,99 +50,103 @@ export default {
components: { treeTable }, components: { treeTable },
data() { data() {
return { return {
defaultExpandAll: false,
showCheckbox: true,
key: 1,
columns: [ columns: [
{ {
text: '事件', label: 'Checkbox',
value: 'event', checkbox: true
width: 200
}, },
{ {
text: 'ID', label: '',
value: 'id' key: 'id',
expand: true
}, },
{ {
text: '时间线', label: 'Event',
value: 'timeLine' key: 'event',
width: 200,
align: 'left'
}, },
{ {
text: '备注', label: 'Scope',
value: 'comment' key: 'scope'
},
{
label: 'Operation',
key: 'operation'
} }
], ],
data: [ data: [
{ {
id: 0, id: 0,
event: '事件1', event: 'Event-0',
timeLine: 50, timeLine: 50
comment: '无'
}, },
{ {
id: 1, id: 1,
event: '事件1', event: 'Event-1',
timeLine: 100, timeLine: 100,
comment: '无',
children: [ children: [
{ {
id: 2, id: 2,
event: '事件2', event: 'Event-2',
timeLine: 10, timeLine: 10
comment: '无'
}, },
{ {
id: 3, id: 3,
event: '事件3', event: 'Event-3',
timeLine: 90, timeLine: 90,
comment: '无',
children: [ children: [
{ {
id: 4, id: 4,
event: '事件4', event: 'Event-4',
timeLine: 5, timeLine: 5
comment: '无'
}, },
{ {
id: 5, id: 5,
event: '事件5', event: 'Event-5',
timeLine: 10, timeLine: 10
comment: '无'
}, },
{ {
id: 6, id: 6,
event: '事件6', event: 'Event-6',
timeLine: 75, timeLine: 75,
comment: '无',
children: [ children: [
{ {
id: 7, id: 7,
event: '事件7', event: 'Event-7',
timeLine: 50, timeLine: 50,
comment: '无',
children: [ children: [
{ {
id: 71, id: 71,
event: '事件71', event: 'Event-7-1',
timeLine: 25, timeLine: 25
comment: 'xx'
}, },
{ {
id: 72, id: 72,
event: '事件72', event: 'Event-7-2',
timeLine: 5, timeLine: 5
comment: 'xx'
}, },
{ {
id: 73, id: 73,
event: '事件73', event: 'Event-7-3',
timeLine: 20, timeLine: 20
comment: 'xx'
} }
] ]
}, },
{ {
id: 8, id: 8,
event: '事件8', event: 'Event-8',
timeLine: 25, timeLine: 25
comment: '无'
} }
] ]
} }
@ -124,6 +156,34 @@ export default {
} }
] ]
} }
},
watch: {
showCheckbox(val) {
if (val) {
this.columns.unshift({
label: 'Checkbox',
checkbox: true
})
} else {
this.columns.shift()
}
this.reset()
}
},
methods: {
reset() {
++this.key
},
click(scope) {
console.log(scope)
}
} }
} }
</script> </script>
<style scoped>
.option-item{
display: inline-block;
margin-right: 15px;
}
</style>