perf[Tree-Table]: refactor tree-table
This commit is contained in:
		@@ -1,29 +1,48 @@
 | 
			
		||||
/**
 | 
			
		||||
* @Author: jianglei
 | 
			
		||||
* @Date:   2017-10-12 12:06:49
 | 
			
		||||
*/
 | 
			
		||||
'use strict'
 | 
			
		||||
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 = []
 | 
			
		||||
  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)
 | 
			
		||||
    }
 | 
			
		||||
    tmp.push(record)
 | 
			
		||||
    if (record.children && record.children.length > 0) {
 | 
			
		||||
      const children = treeToArray(record.children, expandAll, record, _level)
 | 
			
		||||
      tmp = tmp.concat(children)
 | 
			
		||||
  data.forEach((item, index) => {
 | 
			
		||||
    Vue.set(item, '_index', index)
 | 
			
		||||
    tmp.push(item)
 | 
			
		||||
    if (item[children] && item[children].length > 0) {
 | 
			
		||||
      const res = treeToArray(item[children], children)
 | 
			
		||||
      tmp = tmp.concat(res)
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,127 +1,183 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <el-table :data="formatData" :row-style="showRow" v-bind="$attrs">
 | 
			
		||||
    <el-table-column v-if="columns.length===0" width="150">
 | 
			
		||||
  <el-table :data="tableData" :row-style="showRow" v-bind="$attrs" v-on="$listeners" >
 | 
			
		||||
    <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">
 | 
			
		||||
        <span v-for="space in scope.row._level" :key="space" class="ms-tree-space"/>
 | 
			
		||||
        <span v-if="iconShow(0,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.$index }}
 | 
			
		||||
        <slot :scope="scope" :name="item.key">
 | 
			
		||||
          <template v-if="item.expand">
 | 
			
		||||
            <span :style="{'padding-left':+scope.row._level*indent + 'px'} "/>
 | 
			
		||||
            <span v-show="showSperadIcon(scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">
 | 
			
		||||
              <i v-if="!scope.row._expand" class="el-icon-plus" />
 | 
			
		||||
              <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>
 | 
			
		||||
    </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>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
/**
 | 
			
		||||
  Auth: Lei.j1ang
 | 
			
		||||
  Created: 2018/1/19-13:59
 | 
			
		||||
*/
 | 
			
		||||
import treeToArray from './eval'
 | 
			
		||||
import treeToArray, { addAttrs } from './eval.js'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'TreeTable',
 | 
			
		||||
  props: {
 | 
			
		||||
    /* eslint-disable */
 | 
			
		||||
    data: {
 | 
			
		||||
      type: [Array, Object],
 | 
			
		||||
      required: true
 | 
			
		||||
      type: Array,
 | 
			
		||||
      required: true,
 | 
			
		||||
      default: () => []
 | 
			
		||||
    },
 | 
			
		||||
    columns: {
 | 
			
		||||
      type: Array,
 | 
			
		||||
      default: () => []
 | 
			
		||||
    },
 | 
			
		||||
    evalFunc: Function,
 | 
			
		||||
    evalArgs: Array,
 | 
			
		||||
    expandAll: {
 | 
			
		||||
    defaultExpandAll: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false
 | 
			
		||||
    },
 | 
			
		||||
    defaultChildren: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'children'
 | 
			
		||||
    },
 | 
			
		||||
    indent: {
 | 
			
		||||
      type: Number,
 | 
			
		||||
      default: 50
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      guard: 1
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    // 格式化数据源
 | 
			
		||||
    formatData: function() {
 | 
			
		||||
      let tmp
 | 
			
		||||
      if (!Array.isArray(this.data)) {
 | 
			
		||||
        tmp = [this.data]
 | 
			
		||||
      } else {
 | 
			
		||||
        tmp = this.data
 | 
			
		||||
    children() {
 | 
			
		||||
      return this.defaultChildren
 | 
			
		||||
    },
 | 
			
		||||
    tableData() {
 | 
			
		||||
      const data = this.data
 | 
			
		||||
      if (this.data.length === 0) {
 | 
			
		||||
        return []
 | 
			
		||||
      }
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
      const func = this.evalFunc || treeToArray
 | 
			
		||||
      const args = this.evalArgs ? [].concat([tmp, this.expandAll], this.evalArgs) : [tmp, this.expandAll]
 | 
			
		||||
      return func.apply(null, args)
 | 
			
		||||
=======
 | 
			
		||||
      addAttrs(data, {
 | 
			
		||||
        expand: this.defaultExpandAll,
 | 
			
		||||
        children: this.defaultChildren
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      const retval = treeToArray(data, this.defaultChildren)
 | 
			
		||||
      return retval
 | 
			
		||||
>>>>>>> dc6030b... perf[Tree-Table]: refactor tree-table (#1587)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    showRow: function(row) {
 | 
			
		||||
      const show = (row.row.parent ? (row.row.parent._expanded && row.row.parent._show) : true)
 | 
			
		||||
      row.row._show = show
 | 
			
		||||
      return show ? 'animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;' : 'display:none;'
 | 
			
		||||
    addBrother(row, data) {
 | 
			
		||||
      if (row._parent) {
 | 
			
		||||
        row._parent.children.push(data)
 | 
			
		||||
      } else {
 | 
			
		||||
        this.data.push(data)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    // 切换下级是否展开
 | 
			
		||||
    toggleExpanded: function(trIndex) {
 | 
			
		||||
      const record = this.formatData[trIndex]
 | 
			
		||||
      record._expanded = !record._expanded
 | 
			
		||||
    addChild(row, data) {
 | 
			
		||||
      if (!row.children) {
 | 
			
		||||
        this.$set(row, 'children', [])
 | 
			
		||||
      }
 | 
			
		||||
      row.children.push(data)
 | 
			
		||||
    },
 | 
			
		||||
    // 图标显示
 | 
			
		||||
    iconShow(index, record) {
 | 
			
		||||
      return (index === 0 && record.children && record.children.length > 0)
 | 
			
		||||
    delete(row) {
 | 
			
		||||
      const { _index, _parent } = row
 | 
			
		||||
      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>
 | 
			
		||||
<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>
 | 
			
		||||
  $color-blue: #2196F3;
 | 
			
		||||
  $space-width: 18px;
 | 
			
		||||
  .ms-tree-space {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    top: 1px;
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    font-style: normal;
 | 
			
		||||
    font-weight: 400;
 | 
			
		||||
    line-height: 1;
 | 
			
		||||
    width: $space-width;
 | 
			
		||||
    height: 14px;
 | 
			
		||||
    &::before {
 | 
			
		||||
      content: ""
 | 
			
		||||
    }
 | 
			
		||||
<style>
 | 
			
		||||
@keyframes treeTableShow {
 | 
			
		||||
  from {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
  }
 | 
			
		||||
  .processContainer{
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
  to {
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
  }
 | 
			
		||||
  table td {
 | 
			
		||||
    line-height: 26px;
 | 
			
		||||
}
 | 
			
		||||
@-webkit-keyframes treeTableShow {
 | 
			
		||||
  from {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
  }
 | 
			
		||||
  to {
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  .tree-ctrl{
 | 
			
		||||
    position: relative;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    color: $color-blue;
 | 
			
		||||
    margin-left: -$space-width;
 | 
			
		||||
  }
 | 
			
		||||
.tree-ctrl {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  color: #2196f3;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,89 +1,99 @@
 | 
			
		||||
## 写在前面
 | 
			
		||||
此组件仅提供一个创建TreeTable的解决思路
 | 
			
		||||
 | 
			
		||||
## prop说明
 | 
			
		||||
#### *data*
 | 
			
		||||
  **必填**
 | 
			
		||||
此组件仅提供一个创建 TreeTable 的解决思路,本组件充分利用 vue 插槽的特性,方便用户自定义
 | 
			
		||||
 | 
			
		||||
  原始数据,要求是一个数组或者对象
 | 
			
		||||
  ```javascript
 | 
			
		||||
    [{
 | 
			
		||||
      key1: value1,
 | 
			
		||||
      key2: value2,
 | 
			
		||||
      children: [{
 | 
			
		||||
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
 | 
			
		||||
      }]
 | 
			
		||||
    }
 | 
			
		||||
  ```
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key1: value1
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### columns
 | 
			
		||||
  列属性,要求是一个数组
 | 
			
		||||
或者
 | 
			
		||||
 | 
			
		||||
  1. text: 显示在表头的文字
 | 
			
		||||
  2. value: 对应data的key。treeTable将显示相应的value
 | 
			
		||||
  3. width: 每列的宽度,为一个数字(可选)
 | 
			
		||||
```javascript
 | 
			
		||||
   {
 | 
			
		||||
     key1: value1,
 | 
			
		||||
     key2: value2,
 | 
			
		||||
     children: [{
 | 
			
		||||
       key1: value1
 | 
			
		||||
     },
 | 
			
		||||
     {
 | 
			
		||||
       key1: value1
 | 
			
		||||
     }]
 | 
			
		||||
   }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
  如果你想要每个字段都有自定义的样式或者嵌套其他组件,columns可不提供,直接像在el-table一样写即可,如果没有自定义内容,提供columns将更加的便捷方便
 | 
			
		||||
- columns
 | 
			
		||||
 | 
			
		||||
  如果你有几个字段是需要自定义的,几个不需要,那么可以将不需要自定义的字段放入columns,将需要自定义的内容放入到slot中,详情见后文
 | 
			
		||||
  ```javascript
 | 
			
		||||
  [{
 | 
			
		||||
    value:string,
 | 
			
		||||
    text:string,
 | 
			
		||||
    width:number
 | 
			
		||||
  },{
 | 
			
		||||
    value:string,
 | 
			
		||||
    text:string,
 | 
			
		||||
    width:number
 | 
			
		||||
  }]
 | 
			
		||||
  ```
 | 
			
		||||
1. label: 显示在表头的文字
 | 
			
		||||
2. key: 对应 data 的 key。treeTable 将显示相应的 value
 | 
			
		||||
3. width: 每列的宽度,为一个数字(可选)
 | 
			
		||||
 | 
			
		||||
#### expandAll
 | 
			
		||||
  是否默认全部展开,boolean值,默认为false
 | 
			
		||||
树表组件将会根据 columns 的 key 属性生成具名插槽,如果你需要对列数据进行自定义,通过插槽即可实现
 | 
			
		||||
 | 
			
		||||
#### evalFunc
 | 
			
		||||
  解析函数,function,非必须
 | 
			
		||||
```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
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
  如果不提供,将使用默认的[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了
 | 
			
		||||
 | 
			
		||||
  具体可参考[*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
 | 
			
		||||
如果有其他的需求,请参考[el-table](http://element-cn.eleme.io/#/en-US/component/table)的 api 自行修改 index.vue
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								src/mock/table.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/mock/table.js
									
									
									
									
									
										Normal 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
 | 
			
		||||
}
 | 
			
		||||
@@ -1,137 +1,162 @@
 | 
			
		||||
<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;">
 | 
			
		||||
      <a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a>
 | 
			
		||||
    </el-tag>
 | 
			
		||||
      <tree-table
 | 
			
		||||
        ref="TreeTable"
 | 
			
		||||
        :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>
 | 
			
		||||
      <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 slot="selection">
 | 
			
		||||
          <el-table-column type="selection" align="center" width="55"/>
 | 
			
		||||
        </template>
 | 
			
		||||
      </el-table-column>
 | 
			
		||||
      <el-table-column label="时间线">
 | 
			
		||||
        <template slot-scope="scope">
 | 
			
		||||
 | 
			
		||||
        <template slot="pre-column">
 | 
			
		||||
          <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">
 | 
			
		||||
            <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' }"
 | 
			
		||||
                :style="{ width:(scope.row.timeLine||0) * 3+'px',
 | 
			
		||||
                          background:scope.row.timeLine>50?'rgba(233,0,0,.5)':'rgba(0,0,233,0.5)',
 | 
			
		||||
                          marginLeft:scope.row._level * 50+'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 slot="append" slot-scope="{scope}">
 | 
			
		||||
          <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>
 | 
			
		||||
      </el-table-column>
 | 
			
		||||
    </tree-table>
 | 
			
		||||
        <template slot="operation" slot-scope="{scope}">
 | 
			
		||||
          <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>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
/**
 | 
			
		||||
  Auth: Lei.j1ang
 | 
			
		||||
  Created: 2018/1/19-14:54
 | 
			
		||||
*/
 | 
			
		||||
import treeTable from '@/components/TreeTable'
 | 
			
		||||
import treeToArray from './customEval'
 | 
			
		||||
 | 
			
		||||
import TreeTable from '@/components/TreeTable'
 | 
			
		||||
import { data } from './data.js'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'CustomTreeTableDemo',
 | 
			
		||||
  components: { treeTable },
 | 
			
		||||
  components: { TreeTable },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      func: treeToArray,
 | 
			
		||||
      expandAll: false,
 | 
			
		||||
      data:
 | 
			
		||||
      tableData: [],
 | 
			
		||||
      tempItem: {},
 | 
			
		||||
      dialogFormVisible: false,
 | 
			
		||||
      columns: [
 | 
			
		||||
        {
 | 
			
		||||
          id: 1,
 | 
			
		||||
          event: '事件1',
 | 
			
		||||
          timeLine: 100,
 | 
			
		||||
          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: '无'
 | 
			
		||||
                    }
 | 
			
		||||
                  ]
 | 
			
		||||
                }
 | 
			
		||||
              ]
 | 
			
		||||
            }
 | 
			
		||||
          ]
 | 
			
		||||
          label: 'Name',
 | 
			
		||||
          key: 'name',
 | 
			
		||||
          expand: true
 | 
			
		||||
        },
 | 
			
		||||
      args: [null, null, 'timeLine']
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Timeline',
 | 
			
		||||
          key: 'timeline'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Append',
 | 
			
		||||
          key: 'append',
 | 
			
		||||
          width: 300
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Operation',
 | 
			
		||||
          key: 'operation',
 | 
			
		||||
          width: 160
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.getData()
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    message(row) {
 | 
			
		||||
      this.$message.info(row.event)
 | 
			
		||||
    getData() {
 | 
			
		||||
      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)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										49
									
								
								src/views/table/treeTable/data.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/views/table/treeTable/data.js
									
									
									
									
									
										Normal 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
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
@@ -1,20 +1,48 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <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>
 | 
			
		||||
    <div style="margin-bottom:20px;">
 | 
			
		||||
 | 
			
		||||
    <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>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
/**
 | 
			
		||||
  Auth: Lei.j1ang
 | 
			
		||||
  Created: 2018/1/19-14:54
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import treeTable from '@/components/TreeTable'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
@@ -22,99 +50,103 @@ export default {
 | 
			
		||||
  components: { treeTable },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      defaultExpandAll: false,
 | 
			
		||||
      showCheckbox: true,
 | 
			
		||||
      key: 1,
 | 
			
		||||
      columns: [
 | 
			
		||||
        {
 | 
			
		||||
          text: '事件',
 | 
			
		||||
          value: 'event',
 | 
			
		||||
          width: 200
 | 
			
		||||
          label: 'Checkbox',
 | 
			
		||||
          checkbox: true
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'ID',
 | 
			
		||||
          value: 'id'
 | 
			
		||||
          label: '',
 | 
			
		||||
          key: 'id',
 | 
			
		||||
          expand: true
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: '时间线',
 | 
			
		||||
          value: 'timeLine'
 | 
			
		||||
          label: 'Event',
 | 
			
		||||
          key: 'event',
 | 
			
		||||
          width: 200,
 | 
			
		||||
          align: 'left'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: '备注',
 | 
			
		||||
          value: 'comment'
 | 
			
		||||
          label: 'Scope',
 | 
			
		||||
          key: 'scope'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Operation',
 | 
			
		||||
          key: 'operation'
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      data: [
 | 
			
		||||
        {
 | 
			
		||||
          id: 0,
 | 
			
		||||
          event: '事件1',
 | 
			
		||||
          timeLine: 50,
 | 
			
		||||
          comment: '无'
 | 
			
		||||
          event: 'Event-0',
 | 
			
		||||
          timeLine: 50
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          id: 1,
 | 
			
		||||
          event: '事件1',
 | 
			
		||||
          event: 'Event-1',
 | 
			
		||||
          timeLine: 100,
 | 
			
		||||
          comment: '无',
 | 
			
		||||
          children: [
 | 
			
		||||
            {
 | 
			
		||||
              id: 2,
 | 
			
		||||
              event: '事件2',
 | 
			
		||||
              timeLine: 10,
 | 
			
		||||
              comment: '无'
 | 
			
		||||
              event: 'Event-2',
 | 
			
		||||
              timeLine: 10
 | 
			
		||||
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              id: 3,
 | 
			
		||||
              event: '事件3',
 | 
			
		||||
              event: 'Event-3',
 | 
			
		||||
              timeLine: 90,
 | 
			
		||||
              comment: '无',
 | 
			
		||||
              children: [
 | 
			
		||||
                {
 | 
			
		||||
                  id: 4,
 | 
			
		||||
                  event: '事件4',
 | 
			
		||||
                  timeLine: 5,
 | 
			
		||||
                  comment: '无'
 | 
			
		||||
                  event: 'Event-4',
 | 
			
		||||
                  timeLine: 5
 | 
			
		||||
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                  id: 5,
 | 
			
		||||
                  event: '事件5',
 | 
			
		||||
                  timeLine: 10,
 | 
			
		||||
                  comment: '无'
 | 
			
		||||
                  event: 'Event-5',
 | 
			
		||||
                  timeLine: 10
 | 
			
		||||
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                  id: 6,
 | 
			
		||||
                  event: '事件6',
 | 
			
		||||
                  event: 'Event-6',
 | 
			
		||||
                  timeLine: 75,
 | 
			
		||||
                  comment: '无',
 | 
			
		||||
 | 
			
		||||
                  children: [
 | 
			
		||||
                    {
 | 
			
		||||
                      id: 7,
 | 
			
		||||
                      event: '事件7',
 | 
			
		||||
                      event: 'Event-7',
 | 
			
		||||
                      timeLine: 50,
 | 
			
		||||
                      comment: '无',
 | 
			
		||||
 | 
			
		||||
                      children: [
 | 
			
		||||
                        {
 | 
			
		||||
                          id: 71,
 | 
			
		||||
                          event: '事件71',
 | 
			
		||||
                          timeLine: 25,
 | 
			
		||||
                          comment: 'xx'
 | 
			
		||||
                          event: 'Event-7-1',
 | 
			
		||||
                          timeLine: 25
 | 
			
		||||
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                          id: 72,
 | 
			
		||||
                          event: '事件72',
 | 
			
		||||
                          timeLine: 5,
 | 
			
		||||
                          comment: 'xx'
 | 
			
		||||
                          event: 'Event-7-2',
 | 
			
		||||
                          timeLine: 5
 | 
			
		||||
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                          id: 73,
 | 
			
		||||
                          event: '事件73',
 | 
			
		||||
                          timeLine: 20,
 | 
			
		||||
                          comment: 'xx'
 | 
			
		||||
                          event: 'Event-7-3',
 | 
			
		||||
                          timeLine: 20
 | 
			
		||||
                        }
 | 
			
		||||
                      ]
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                      id: 8,
 | 
			
		||||
                      event: '事件8',
 | 
			
		||||
                      timeLine: 25,
 | 
			
		||||
                      comment: '无'
 | 
			
		||||
                      event: 'Event-8',
 | 
			
		||||
                      timeLine: 25
 | 
			
		||||
                    }
 | 
			
		||||
                  ]
 | 
			
		||||
                }
 | 
			
		||||
@@ -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>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
.option-item{
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  margin-right: 15px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user