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'
// 给数据添加额外的几个属性,并且扁平化数组
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

View File

@ -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)
})

View File

@ -80,7 +80,25 @@ const columns = [
#### 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>
</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)
})
}
}
}
}