add custom feature like checkbox
This commit is contained in:
parent
a42f471208
commit
f9668fb29c
|
@ -1,24 +1,29 @@
|
|||
import Vue from 'vue'
|
||||
|
||||
// 给数据添加额外的几个属性,并且扁平化数组
|
||||
export default function formatData(
|
||||
export default function treeToTable(
|
||||
data,
|
||||
{ parent = null, leavel = 0, expand = false } = {}
|
||||
{ parent = null, leavel = 0, expand = false, children = 'children', show = true, select = false } = {}
|
||||
) {
|
||||
console.log('data', data)
|
||||
let tmp = []
|
||||
data.forEach(item => {
|
||||
Vue.set(item, '__leavel', leavel)
|
||||
Vue.set(item, '__expand', expand)
|
||||
Vue.set(item, '__parent', parent)
|
||||
Vue.set(item, '__show', show)
|
||||
Vue.set(item, '__select', select)
|
||||
|
||||
tmp.push(item)
|
||||
if (item.children && item.children.length > 0) {
|
||||
const children = formatData(item.children, {
|
||||
if (item[children] && item[children].length > 0) {
|
||||
const res = treeToTable(item[children], {
|
||||
parent: item,
|
||||
leavel: leavel + 1
|
||||
leavel: leavel + 1,
|
||||
expand,
|
||||
children,
|
||||
status,
|
||||
select
|
||||
})
|
||||
tmp = tmp.concat(children)
|
||||
tmp = tmp.concat(res)
|
||||
}
|
||||
})
|
||||
return tmp
|
||||
|
|
|
@ -1,26 +1,30 @@
|
|||
<template>
|
||||
<el-table :data="res" :row-style="isShowRow" border style="width: 100%">
|
||||
<el-table-column
|
||||
v-for="(item,idx) in columns"
|
||||
v-for="item in columns"
|
||||
:label="item.label"
|
||||
:key="item.key"
|
||||
:width="item.width"
|
||||
align="center"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span
|
||||
v-if="isNotLastChild(idx,scope.row)"
|
||||
class="tree-ctrl"
|
||||
@click="toggleExpanded(scope.$index)"
|
||||
>
|
||||
<i
|
||||
v-if="!scope.row.__expand"
|
||||
:style="{'padding-left':+scope.row.__leavel*50 + 'px'} "
|
||||
class="el-icon-plus"
|
||||
/>
|
||||
<i v-else :style="{'padding-left':+scope.row.__leavel*50 + 'px'} " class="el-icon-minus"/>
|
||||
</span>
|
||||
<slot :scope="scope" :name="item.key">{{ scope.row[item.key] }}</slot>
|
||||
<slot :scope="scope" :name="item.key">
|
||||
<template v-if="item.key==='__sperad'">
|
||||
<span
|
||||
v-show="isShowSperadIcon(scope.row)"
|
||||
class="tree-ctrl"
|
||||
@click="toggleExpanded(scope.$index)"
|
||||
>
|
||||
<i
|
||||
v-if="!scope.row.__expand"
|
||||
:style="{'padding-left':+scope.row.__leavel*50 + 'px'} "
|
||||
class="el-icon-plus"
|
||||
/>
|
||||
<i v-else :style="{'padding-left':+scope.row.__leavel*50 + 'px'} " class="el-icon-minus"/>
|
||||
</span>
|
||||
</template>
|
||||
{{ scope.row[item.key] }}
|
||||
</slot>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -44,7 +48,7 @@ export default {
|
|||
evalFunc: {
|
||||
type: Function
|
||||
},
|
||||
evalArgs: Array
|
||||
evalArgs: Object
|
||||
/* eslint-enable */
|
||||
},
|
||||
computed: {
|
||||
|
@ -59,30 +63,38 @@ export default {
|
|||
const func = this.evalFunc || treeToArray
|
||||
const args = { ...this.evalArgs }
|
||||
return func(tmp, args)
|
||||
},
|
||||
|
||||
// 自定义的children字段
|
||||
children() {
|
||||
return this.evalArgs && this.evalArgs.children || 'children'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isShowRow: function(row) {
|
||||
const show = row.row.__parent ? row.row.__parent.__expand : true
|
||||
const parent = row.row.__parent
|
||||
const show = parent ? parent.__expand && parent.__show : true
|
||||
row.row.__show = show
|
||||
return show
|
||||
? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;'
|
||||
: 'display:none;'
|
||||
},
|
||||
isNotLastChild(index, record) {
|
||||
return index === 0 && record.children && record.children.length > 0
|
||||
isShowSperadIcon(record) {
|
||||
return record[this.children] && record[this.children].length > 0
|
||||
},
|
||||
toggleExpanded(trIndex) {
|
||||
const record = this.res[trIndex]
|
||||
const expand = !record.__expand
|
||||
record.__expand = expand
|
||||
// 默认收起是全部收起,展开是一级一级展开
|
||||
if (!expand) {
|
||||
this.expandRecursion(record, expand)
|
||||
}
|
||||
// 收起是全部收起,展开是一级一级展开
|
||||
// if (!expand) {
|
||||
// this.expandRecursion(record, expand)
|
||||
// }
|
||||
},
|
||||
expandRecursion(row, expand) {
|
||||
if (row.children && row.children.length > 0) {
|
||||
row.children.map(child => {
|
||||
const children = row[this.children]
|
||||
if (children && children.length > 0) {
|
||||
children.map(child => {
|
||||
child.__expand = expand
|
||||
this.expandRecursion(child, expand)
|
||||
})
|
||||
|
|
|
@ -80,7 +80,25 @@ const columns = [
|
|||
|
||||
#### evalArgs
|
||||
|
||||
解析函数的参数,是一个对象,如果需要展开所有的数据,那么就传入`{expand:true}`
|
||||
解析函数的参数,是一个对象,
|
||||
|
||||
- parent = null
|
||||
|
||||
树的顶层节点默认为 null
|
||||
|
||||
- leavel = 0
|
||||
|
||||
默认第一层级为0,然后依次递增
|
||||
|
||||
- expand = false
|
||||
|
||||
如果需要展开所有的数据,那么就传入`{expand:true}`
|
||||
|
||||
- children = 'children'
|
||||
|
||||
如果后台返回的数据不都是带有children字段,那么修改一下即可
|
||||
|
||||
|
||||
|
||||
## 其他
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -5,109 +5,111 @@
|
|||
<a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a>
|
||||
</el-tag>
|
||||
|
||||
<tree-table :data="data" :eval-func="func" :eval-args="args" :expand-all="expandAll" border>
|
||||
<el-table-column label="事件">
|
||||
<template slot-scope="scope">
|
||||
<span style="color:sandybrown">{{ scope.row.event }}</span>
|
||||
<el-tag>{{ scope.row.timeLine+'ms' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="时间线">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip :content="scope.row.timeLine+'ms'" effect="dark" placement="left">
|
||||
<div class="processContainer">
|
||||
<div
|
||||
:style="{ width:scope.row._width * 500+'px',
|
||||
background:scope.row._width>0.5?'rgba(233,0,0,.5)':'rgba(0,0,233,0.5)',
|
||||
marginLeft:scope.row._marginLeft * 500+'px' }"
|
||||
class="process">
|
||||
<span style="display:inline-block"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click="message(scope.row)">点击</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<tree-table :data="data" :columns="columns" :eval-args="args" border>
|
||||
<template slot="__checkbox" slot-scope="{scope}">
|
||||
<!-- 默认leaval 为 0 的时候,提供全选操作 -->
|
||||
<el-checkbox v-if="scope.row[children]&&scope.row[children].length>0" :style="{'padding-left':+scope.row.__leavel*50 + 'px'} " :indeterminate="scope.row.__select" v-model="scope.row.__select" @change="handleCheckAllChange(scope.row)">全</el-checkbox>
|
||||
<el-checkbox v-else :style="{'padding-left':+scope.row.__leavel*50 + 'px'} " v-model="scope.row.__select" @change="handleCheckAllChange(scope.row)">选</el-checkbox>
|
||||
</template>
|
||||
</tree-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
Auth: Lei.j1ang
|
||||
Created: 2018/1/19-14:54
|
||||
*/
|
||||
|
||||
import treeTable from '@/components/TreeTable'
|
||||
import treeToArray from './customEval'
|
||||
|
||||
export default {
|
||||
name: 'CustomTreeTableDemo',
|
||||
components: { treeTable },
|
||||
data() {
|
||||
return {
|
||||
func: treeToArray,
|
||||
expandAll: false,
|
||||
columns: [
|
||||
{
|
||||
label: '操作',
|
||||
key: '__checkbox',
|
||||
width: 400
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
key: '__sperad',
|
||||
width: 400
|
||||
},
|
||||
{
|
||||
label: 'ID',
|
||||
key: 'id'
|
||||
},
|
||||
{
|
||||
label: '事件',
|
||||
key: 'event',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
label: '时间线',
|
||||
key: 'timeLine'
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
key: 'comment'
|
||||
}
|
||||
],
|
||||
data:
|
||||
{
|
||||
id: 1,
|
||||
event: '事件1',
|
||||
timeLine: 100,
|
||||
comment: '无',
|
||||
children: [
|
||||
son: [
|
||||
{
|
||||
id: 2,
|
||||
id: 1.1,
|
||||
event: '事件2',
|
||||
timeLine: 10,
|
||||
comment: '无'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
id: 1.2,
|
||||
event: '事件3',
|
||||
timeLine: 90,
|
||||
comment: '无',
|
||||
children: [
|
||||
son: [
|
||||
{
|
||||
id: 4,
|
||||
id: '1.2.1',
|
||||
event: '事件4',
|
||||
timeLine: 5,
|
||||
comment: '无'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
id: '1.2.2',
|
||||
event: '事件5',
|
||||
timeLine: 10,
|
||||
comment: '无'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
id: '1.2.3',
|
||||
event: '事件6',
|
||||
timeLine: 75,
|
||||
comment: '无',
|
||||
children: [
|
||||
son: [
|
||||
{
|
||||
id: 7,
|
||||
id: '1.2.3.1',
|
||||
event: '事件7',
|
||||
timeLine: 50,
|
||||
comment: '无',
|
||||
children: [
|
||||
son: [
|
||||
{
|
||||
id: 71,
|
||||
id: '1.2.3.1.1',
|
||||
event: '事件71',
|
||||
timeLine: 25,
|
||||
comment: 'xx'
|
||||
},
|
||||
{
|
||||
id: 72,
|
||||
id: '1.2.3.1.2',
|
||||
event: '事件72',
|
||||
timeLine: 5,
|
||||
comment: 'xx'
|
||||
},
|
||||
{
|
||||
id: 73,
|
||||
id: '1.2.3.1.3',
|
||||
event: '事件73',
|
||||
timeLine: 20,
|
||||
comment: 'xx'
|
||||
|
@ -115,7 +117,7 @@ export default {
|
|||
]
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
id: '1.2.3.2',
|
||||
event: '事件8',
|
||||
timeLine: 25,
|
||||
comment: '无'
|
||||
|
@ -126,12 +128,34 @@ export default {
|
|||
}
|
||||
]
|
||||
},
|
||||
args: [null, null, 'timeLine']
|
||||
args: { children: 'son' },
|
||||
isIndeterminate: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
children() {
|
||||
return this.evalArgs && this.evalArgs.children || 'children'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
message(row) {
|
||||
this.$message.info(row.event)
|
||||
handleCheckAllChange(row) {
|
||||
this.selcetRecursion(row, row.__select, this.children)
|
||||
this.isIndeterminate = row.__select
|
||||
},
|
||||
selcetRecursion(row, select, children = 'children') {
|
||||
console.log('row', row)
|
||||
console.log('select', select)
|
||||
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)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue