add custom feature like checkbox

This commit is contained in:
liugq 2019-02-13 14:14:12 +08:00
parent a42f471208
commit f9668fb29c
5 changed files with 142 additions and 131 deletions

View File

@ -1,24 +1,29 @@
import Vue from 'vue' import Vue from 'vue'
// 给数据添加额外的几个属性,并且扁平化数组 // 给数据添加额外的几个属性,并且扁平化数组
export default function formatData( export default function treeToTable(
data, 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 = [] let tmp = []
data.forEach(item => { data.forEach(item => {
Vue.set(item, '__leavel', leavel) Vue.set(item, '__leavel', leavel)
Vue.set(item, '__expand', expand) Vue.set(item, '__expand', expand)
Vue.set(item, '__parent', parent) Vue.set(item, '__parent', parent)
Vue.set(item, '__show', show)
Vue.set(item, '__select', select)
tmp.push(item) tmp.push(item)
if (item.children && item.children.length > 0) { if (item[children] && item[children].length > 0) {
const children = formatData(item.children, { const res = treeToTable(item[children], {
parent: item, parent: item,
leavel: leavel + 1 leavel: leavel + 1,
expand,
children,
status,
select
}) })
tmp = tmp.concat(children) tmp = tmp.concat(res)
} }
}) })
return tmp return tmp

View File

@ -1,26 +1,30 @@
<template> <template>
<el-table :data="res" :row-style="isShowRow" border style="width: 100%"> <el-table :data="res" :row-style="isShowRow" border style="width: 100%">
<el-table-column <el-table-column
v-for="(item,idx) in columns" v-for="item in columns"
:label="item.label" :label="item.label"
:key="item.key" :key="item.key"
:width="item.width" :width="item.width"
align="center" align="center"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<span <slot :scope="scope" :name="item.key">
v-if="isNotLastChild(idx,scope.row)" <template v-if="item.key==='__sperad'">
class="tree-ctrl" <span
@click="toggleExpanded(scope.$index)" v-show="isShowSperadIcon(scope.row)"
> class="tree-ctrl"
<i @click="toggleExpanded(scope.$index)"
v-if="!scope.row.__expand" >
:style="{'padding-left':+scope.row.__leavel*50 + 'px'} " <i
class="el-icon-plus" v-if="!scope.row.__expand"
/> :style="{'padding-left':+scope.row.__leavel*50 + 'px'} "
<i v-else :style="{'padding-left':+scope.row.__leavel*50 + 'px'} " class="el-icon-minus"/> class="el-icon-plus"
</span> />
<slot :scope="scope" :name="item.key">{{ scope.row[item.key] }}</slot> <i v-else :style="{'padding-left':+scope.row.__leavel*50 + 'px'} " class="el-icon-minus"/>
</span>
</template>
{{ scope.row[item.key] }}
</slot>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -44,7 +48,7 @@ export default {
evalFunc: { evalFunc: {
type: Function type: Function
}, },
evalArgs: Array evalArgs: Object
/* eslint-enable */ /* eslint-enable */
}, },
computed: { computed: {
@ -59,30 +63,38 @@ export default {
const func = this.evalFunc || treeToArray const func = this.evalFunc || treeToArray
const args = { ...this.evalArgs } const args = { ...this.evalArgs }
return func(tmp, args) return func(tmp, args)
},
// children
children() {
return this.evalArgs && this.evalArgs.children || 'children'
} }
}, },
methods: { methods: {
isShowRow: function(row) { 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 return show
? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;' ? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;'
: 'display:none;' : 'display:none;'
}, },
isNotLastChild(index, record) { isShowSperadIcon(record) {
return index === 0 && record.children && record.children.length > 0 return record[this.children] && record[this.children].length > 0
}, },
toggleExpanded(trIndex) { toggleExpanded(trIndex) {
const record = this.res[trIndex] const record = this.res[trIndex]
const expand = !record.__expand const expand = !record.__expand
record.__expand = expand record.__expand = expand
// //
if (!expand) { // if (!expand) {
this.expandRecursion(record, expand) // this.expandRecursion(record, expand)
} // }
}, },
expandRecursion(row, expand) { expandRecursion(row, expand) {
if (row.children && row.children.length > 0) { const children = row[this.children]
row.children.map(child => { if (children && children.length > 0) {
children.map(child => {
child.__expand = expand child.__expand = expand
this.expandRecursion(child, expand) this.expandRecursion(child, expand)
}) })

View File

@ -80,7 +80,25 @@ const columns = [
#### evalArgs #### evalArgs
解析函数的参数,是一个对象,如果需要展开所有的数据,那么就传入`{expand:true}` 解析函数的参数,是一个对象,
- parent = null
树的顶层节点默认为 null
- leavel = 0
默认第一层级为0然后依次递增
- expand = false
如果需要展开所有的数据,那么就传入`{expand:true}`
- children = 'children'
如果后台返回的数据不都是带有children字段那么修改一下即可
## 其他 ## 其他

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

@ -5,109 +5,111 @@
<a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a> <a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a>
</el-tag> </el-tag>
<tree-table :data="data" :eval-func="func" :eval-args="args" :expand-all="expandAll" border> <tree-table :data="data" :columns="columns" :eval-args="args" border>
<el-table-column label="事件"> <template slot="__checkbox" slot-scope="{scope}">
<template slot-scope="scope"> <!-- 默认leaval 0 的时候提供全选操作 -->
<span style="color:sandybrown">{{ scope.row.event }}</span> <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-tag>{{ scope.row.timeLine+'ms' }}</el-tag> <el-checkbox v-else :style="{'padding-left':+scope.row.__leavel*50 + 'px'} " v-model="scope.row.__select" @change="handleCheckAllChange(scope.row)"></el-checkbox>
</template> </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> </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'
import treeToArray from './customEval'
export default { export default {
name: 'CustomTreeTableDemo', name: 'CustomTreeTableDemo',
components: { treeTable }, components: { treeTable },
data() { data() {
return { return {
func: treeToArray, columns: [
expandAll: false, {
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: data:
{ {
id: 1, id: 1,
event: '事件1', event: '事件1',
timeLine: 100, timeLine: 100,
comment: '无', comment: '无',
children: [ son: [
{ {
id: 2, id: 1.1,
event: '事件2', event: '事件2',
timeLine: 10, timeLine: 10,
comment: '无' comment: '无'
}, },
{ {
id: 3, id: 1.2,
event: '事件3', event: '事件3',
timeLine: 90, timeLine: 90,
comment: '无', comment: '无',
children: [ son: [
{ {
id: 4, id: '1.2.1',
event: '事件4', event: '事件4',
timeLine: 5, timeLine: 5,
comment: '无' comment: '无'
}, },
{ {
id: 5, id: '1.2.2',
event: '事件5', event: '事件5',
timeLine: 10, timeLine: 10,
comment: '无' comment: '无'
}, },
{ {
id: 6, id: '1.2.3',
event: '事件6', event: '事件6',
timeLine: 75, timeLine: 75,
comment: '无', comment: '无',
children: [ son: [
{ {
id: 7, id: '1.2.3.1',
event: '事件7', event: '事件7',
timeLine: 50, timeLine: 50,
comment: '无', comment: '无',
children: [ son: [
{ {
id: 71, id: '1.2.3.1.1',
event: '事件71', event: '事件71',
timeLine: 25, timeLine: 25,
comment: 'xx' comment: 'xx'
}, },
{ {
id: 72, id: '1.2.3.1.2',
event: '事件72', event: '事件72',
timeLine: 5, timeLine: 5,
comment: 'xx' comment: 'xx'
}, },
{ {
id: 73, id: '1.2.3.1.3',
event: '事件73', event: '事件73',
timeLine: 20, timeLine: 20,
comment: 'xx' comment: 'xx'
@ -115,7 +117,7 @@ export default {
] ]
}, },
{ {
id: 8, id: '1.2.3.2',
event: '事件8', event: '事件8',
timeLine: 25, timeLine: 25,
comment: '无' 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: { methods: {
message(row) { handleCheckAllChange(row) {
this.$message.info(row.event) 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)
})
}
} }
} }
} }