220
									
								
								src/components/TreeTable/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								src/components/TreeTable/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,220 @@
 | 
			
		||||
 | 
			
		||||
- [Enlgish](#Brief)
 | 
			
		||||
 | 
			
		||||
# 中文
 | 
			
		||||
 | 
			
		||||
## 写在前面
 | 
			
		||||
 | 
			
		||||
此组件仅提供一个创建 `TreeTable` 的解决思路。它基于`element-ui`的 table 组件实现,通过`el-table`的`row-style`方法,在里面判断元素是否需要隐藏或者显示,从而实现`TreeTable`的展开与收起。
 | 
			
		||||
 | 
			
		||||
并且本组件充分利用 `vue` 插槽的特性来方便用户自定义。
 | 
			
		||||
 | 
			
		||||
`evel.js` 里面,`addAttrs` 方法会给数据添加几个属性,`treeTotable` 会对数组扁平化。这些操作都不会破坏源数据,只是会新增属性。
 | 
			
		||||
 | 
			
		||||
## Props 说明
 | 
			
		||||
 | 
			
		||||
|    Attribute     | Description                        |  Type   | Default  |
 | 
			
		||||
| :--------------: | :--------------------------------- | :-----: | :------: |
 | 
			
		||||
|       data       | 原始展示数据                       |  Array  |    []    |
 | 
			
		||||
|     columns      | 列属性                             |  Array  |    []    |
 | 
			
		||||
| defaultExpandAll | 默认是否全部展开                   | Boolean |  false   |
 | 
			
		||||
| defaultChildren  | 指定子树为节点对象的某个属性值     | String  | children |  |
 | 
			
		||||
|      indent      | 相邻级节点间的水平缩进,单位为像素 | Number  |    50    |
 | 
			
		||||
 | 
			
		||||
> 任何 `el-table` 的属性都支持,例如`border`、`fit`、`size`或者`@select`、`@cell-click`等方法。详情属性见`el-table`文档。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 代码示例
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<tree-table :data="data" :columns="columns" border>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### data(**必填**)
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const data = [
 | 
			
		||||
  {
 | 
			
		||||
    name:'1'
 | 
			
		||||
    children: [
 | 
			
		||||
      {
 | 
			
		||||
        name: '1-1'
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: '1-2'
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: `2`
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### columns(**必填**)
 | 
			
		||||
 | 
			
		||||
- label: 显示在表头的文字
 | 
			
		||||
- key: 对应 data 的 key。treeTable 将显示相应的 value
 | 
			
		||||
- expand: `true` or `false`。若为 true,则在该列显示展开收起图标
 | 
			
		||||
- checkbox: `true` or `false`。若为 true,则在该列显示`checkbox`
 | 
			
		||||
- width: 每列的宽度,为一个数字(可选)。例如`200`
 | 
			
		||||
- align: 对齐方式 `left/center/right`
 | 
			
		||||
- header-align: 表头对齐方式 `left/center/right`
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
const columns = [
 | 
			
		||||
  {
 | 
			
		||||
    label: 'Checkbox',
 | 
			
		||||
    checkbox: true
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: '',
 | 
			
		||||
    key: 'id',
 | 
			
		||||
    expand: true
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: 'Event',
 | 
			
		||||
    key: 'event',
 | 
			
		||||
    width: 200,
 | 
			
		||||
    align: 'left'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: 'Scope',
 | 
			
		||||
    key: 'scope'
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> 树表组件将会根据 columns 的 key 属性生成具名插槽,如果你需要对列数据进行自定义,通过插槽即可实现
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<template slot="your key" 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>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Events
 | 
			
		||||
 | 
			
		||||
目前提供了几个方法,不过只是`beta`版本,之后很可能会修改。
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
this.$refs.TreeTable.addChild(row, data) //添加子元素
 | 
			
		||||
this.$refs.TreeTable.addBrother(row, data) //添加兄弟元素
 | 
			
		||||
this.$refs.TreeTable.delete(row) //删除该元素
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 其他
 | 
			
		||||
 | 
			
		||||
如果有其他的需求,请参考[el-table](http://element-cn.eleme.io/#/en-US/component/table)的 api 自行修改 index.vue
 | 
			
		||||
 | 
			
		||||
# English
 | 
			
		||||
 | 
			
		||||
## Brief
 | 
			
		||||
 | 
			
		||||
This component only provides a solution for creating `TreeTable`. It is based on the `element-ui` table component. It uses the `row-style` method of `el-table` to determine whether the element needs to be hidden or displayed.
 | 
			
		||||
 | 
			
		||||
And this component makes full use of the features of the `vue` slot to make it user-friendly.
 | 
			
		||||
 | 
			
		||||
In `evel.js`, the `addAttrs` method adds several properties to the data, and `treeTotable` flattens the array. None of these operations will destroy the source data, just add properties.
 | 
			
		||||
 | 
			
		||||
## Props
 | 
			
		||||
 | 
			
		||||
|    Attribute     | Description                                                  |  Type   | Default  |
 | 
			
		||||
| :--------------: | :----------------------------------------------------------- | :-----: | :------: |
 | 
			
		||||
|       data       | original display data                                        |  Array  |    []    |
 | 
			
		||||
|     columns      | column attribute                                             |  Array  |    []    |
 | 
			
		||||
| defaultExpandAll | whether to expand all nodes by default                       | Boolean |  false   |
 | 
			
		||||
| defaultChildren  | specify which node object is used as the node's subtree      | String  | children |  |
 | 
			
		||||
|      indent      | horizontal indentation of nodes in adjacent levels in pixels | Number  |    50    |
 | 
			
		||||
 | 
			
		||||
> Any of the `el-table` properties are supported, such as `border`, `fit`, `size` or `@select`, `@cell-click`. See the ʻel-table` documentation for details.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### Example
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<tree-table :data="data" :columns="columns" border>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### data(**Required**)
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const data = [
 | 
			
		||||
  {
 | 
			
		||||
    name:'1'
 | 
			
		||||
    children: [
 | 
			
		||||
      {
 | 
			
		||||
        name: '1-1'
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: '1-2'
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: `2`
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### columns(**Required**)
 | 
			
		||||
 | 
			
		||||
- label: text displayed in the header
 | 
			
		||||
- key: data.key will show in column
 | 
			
		||||
- expand: `true` or `false`
 | 
			
		||||
- checkbox: `true` or `false`
 | 
			
		||||
- width: column width 。such as `200`
 | 
			
		||||
- align: alignment `left/center/right`
 | 
			
		||||
- header-align: alignment of the table header `left/center/right`
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
const columns = [
 | 
			
		||||
  {
 | 
			
		||||
    label: 'Checkbox',
 | 
			
		||||
    checkbox: true
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: '',
 | 
			
		||||
    key: 'id',
 | 
			
		||||
    expand: true
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: 'Event',
 | 
			
		||||
    key: 'event',
 | 
			
		||||
    width: 200,
 | 
			
		||||
    align: 'left'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: 'Scope',
 | 
			
		||||
    key: 'scope'
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> The tree table component will generate a named slot based on the key property of columns. If you need to customize the column data, you can do it through the slot.
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<template slot="your key" 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>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Events
 | 
			
		||||
 | 
			
		||||
Several methods are currently available, but only the `beta` version, which is likely to be modified later.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
this.$refs.TreeTable.addChild(row, data) //Add child elements
 | 
			
		||||
this.$refs.TreeTable.addBrother(row, data) //Add a sibling element
 | 
			
		||||
this.$refs.TreeTable.delete(row) //Delete the element
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Other
 | 
			
		||||
 | 
			
		||||
If you have other requirements, please refer to the [el-table](http://element-cn.eleme.io/#/en-US/component/table) api to modify the index.vue
 | 
			
		||||
@@ -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,177 @@
 | 
			
		||||
<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"/>
 | 
			
		||||
        <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>
 | 
			
		||||
        {{ scope.$index }}
 | 
			
		||||
          </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 []
 | 
			
		||||
      }
 | 
			
		||||
      const func = this.evalFunc || treeToArray
 | 
			
		||||
      const args = this.evalArgs ? Array.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
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  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">
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
@keyframes treeTableShow {
 | 
			
		||||
    from {opacity: 0;}
 | 
			
		||||
    to {opacity: 1;}
 | 
			
		||||
  from {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
  }
 | 
			
		||||
  to {
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@-webkit-keyframes treeTableShow {
 | 
			
		||||
    from {opacity: 0;}
 | 
			
		||||
    to {opacity: 1;}
 | 
			
		||||
  from {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
  }
 | 
			
		||||
</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: ""
 | 
			
		||||
  to {
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
  .processContainer{
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
  }
 | 
			
		||||
  table td {
 | 
			
		||||
    line-height: 26px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
.tree-ctrl {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
    color: $color-blue;
 | 
			
		||||
    margin-left: -$space-width;
 | 
			
		||||
  color: #2196f3;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,89 +0,0 @@
 | 
			
		||||
## 写在前面
 | 
			
		||||
此组件仅提供一个创建TreeTable的解决思路
 | 
			
		||||
 | 
			
		||||
## prop说明
 | 
			
		||||
#### *data*
 | 
			
		||||
  **必填**
 | 
			
		||||
 | 
			
		||||
  原始数据,要求是一个数组或者对象
 | 
			
		||||
  ```javascript
 | 
			
		||||
    [{
 | 
			
		||||
      key1: value1,
 | 
			
		||||
      key2: value2,
 | 
			
		||||
      children: [{
 | 
			
		||||
        key1: value1
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        key1: value1
 | 
			
		||||
      }]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      key1: value1
 | 
			
		||||
    }]
 | 
			
		||||
  ```
 | 
			
		||||
  或者
 | 
			
		||||
 ```javascript
 | 
			
		||||
    {
 | 
			
		||||
      key1: value1,
 | 
			
		||||
      key2: value2,
 | 
			
		||||
      children: [{
 | 
			
		||||
        key1: value1
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        key1: value1
 | 
			
		||||
      }]
 | 
			
		||||
    }
 | 
			
		||||
  ```
 | 
			
		||||
 | 
			
		||||
#### columns
 | 
			
		||||
  列属性,要求是一个数组
 | 
			
		||||
 | 
			
		||||
  1. text: 显示在表头的文字
 | 
			
		||||
  2. value: 对应data的key。treeTable将显示相应的value
 | 
			
		||||
  3. width: 每列的宽度,为一个数字(可选)
 | 
			
		||||
 | 
			
		||||
  如果你想要每个字段都有自定义的样式或者嵌套其他组件,columns可不提供,直接像在el-table一样写即可,如果没有自定义内容,提供columns将更加的便捷方便
 | 
			
		||||
 | 
			
		||||
  如果你有几个字段是需要自定义的,几个不需要,那么可以将不需要自定义的字段放入columns,将需要自定义的内容放入到slot中,详情见后文
 | 
			
		||||
  ```javascript
 | 
			
		||||
  [{
 | 
			
		||||
    value:string,
 | 
			
		||||
    text:string,
 | 
			
		||||
    width:number
 | 
			
		||||
  },{
 | 
			
		||||
    value:string,
 | 
			
		||||
    text:string,
 | 
			
		||||
    width:number
 | 
			
		||||
  }]
 | 
			
		||||
  ```
 | 
			
		||||
 | 
			
		||||
#### expandAll
 | 
			
		||||
  是否默认全部展开,boolean值,默认为false
 | 
			
		||||
 | 
			
		||||
#### evalFunc
 | 
			
		||||
  解析函数,function,非必须
 | 
			
		||||
 | 
			
		||||
  如果不提供,将使用默认的[evalFunc](./eval.js)
 | 
			
		||||
 | 
			
		||||
  如果提供了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)
 | 
			
		||||
 | 
			
		||||
#### evalArgs
 | 
			
		||||
  解析函数的参数,是一个数组
 | 
			
		||||
 | 
			
		||||
  **请注意,自定义的解析函数参数第一个为this.data,第二个参数为, this.expandAll,你不需要在evalArgs填写。一定记住,这两个参数是强制性的,并且位置不可颠倒** *this.data为需要解析的数据,this.expandAll为是否默认展开*
 | 
			
		||||
 | 
			
		||||
  如你的解析函数需要的参数为`(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
 | 
			
		||||
							
								
								
									
										1
									
								
								src/icons/svg/tree-table.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/icons/svg/tree-table.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M44.8 0h79.543C126.78 0 128 1.422 128 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H44.8c-2.438 0-3.657-1.422-3.657-4.267V4.267C41.143 1.422 42.362 0 44.8 0zm22.857 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 80 64 78.578 64 75.733V52.267C64 49.422 65.219 48 67.657 48zm0 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 128 64 126.578 64 123.733v-23.466C64 97.422 65.219 96 67.657 96zM50.286 68.267c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V32h6.4c2.02 0 3.658-1.91 3.658-4.267V4.267C27.429 1.91 25.79 0 23.77 0H3.657C1.637 0 0 1.91 0 4.267v23.466C0 30.09 1.637 32 3.657 32h6.4v80c0 2.356 1.638 4.267 3.657 4.267h36.572c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V68.267h32.915z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 906 B  | 
							
								
								
									
										0
									
								
								src/mock/table.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/mock/table.js
									
									
									
									
									
										Normal file
									
								
							@@ -10,6 +10,7 @@ import Layout from '@/views/layout/Layout'
 | 
			
		||||
import componentsRouter from './modules/components'
 | 
			
		||||
import chartsRouter from './modules/charts'
 | 
			
		||||
import tableRouter from './modules/table'
 | 
			
		||||
import treeTableRouter from './modules/tree-table'
 | 
			
		||||
import nestedRouter from './modules/nested'
 | 
			
		||||
 | 
			
		||||
/** note: sub-menu only appear when children.length>=1
 | 
			
		||||
@@ -162,6 +163,7 @@ export const asyncRouterMap = [
 | 
			
		||||
  chartsRouter,
 | 
			
		||||
  nestedRouter,
 | 
			
		||||
  tableRouter,
 | 
			
		||||
  treeTableRouter,
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    path: '/example',
 | 
			
		||||
 
 | 
			
		||||
@@ -30,18 +30,6 @@ const tableRouter = {
 | 
			
		||||
      name: 'InlineEditTable',
 | 
			
		||||
      meta: { title: 'inlineEditTable' }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      path: 'tree-table',
 | 
			
		||||
      component: () => import('@/views/table/treeTable/treeTable'),
 | 
			
		||||
      name: 'TreeTableDemo',
 | 
			
		||||
      meta: { title: 'treeTable' }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      path: 'custom-tree-table',
 | 
			
		||||
      component: () => import('@/views/table/treeTable/customTreeTable'),
 | 
			
		||||
      name: 'CustomTreeTableDemo',
 | 
			
		||||
      meta: { title: 'customTreeTable' }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      path: 'complex-table',
 | 
			
		||||
      component: () => import('@/views/table/complexTable'),
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								src/router/modules/tree-table.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/router/modules/tree-table.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
/** When your routing table is too long, you can split it into small modules**/
 | 
			
		||||
 | 
			
		||||
import Layout from '@/views/layout/Layout'
 | 
			
		||||
 | 
			
		||||
const treeTableRouter = {
 | 
			
		||||
  path: '/tree-table',
 | 
			
		||||
  component: Layout,
 | 
			
		||||
  redirect: '/table/complex-table',
 | 
			
		||||
  name: 'TreeTable',
 | 
			
		||||
  meta: {
 | 
			
		||||
    title: 'treeTable',
 | 
			
		||||
    icon: 'tree-table'
 | 
			
		||||
  },
 | 
			
		||||
  children: [
 | 
			
		||||
    {
 | 
			
		||||
      path: 'index',
 | 
			
		||||
      component: () => import('@/views/tree-table/index'),
 | 
			
		||||
      name: 'TreeTableDemo',
 | 
			
		||||
      meta: { title: 'treeTable' }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      path: 'custom',
 | 
			
		||||
      component: () => import('@/views/tree-table/custom'),
 | 
			
		||||
      name: 'CustomTreeTableDemo',
 | 
			
		||||
      meta: { title: 'customTreeTable' }
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
export default treeTableRouter
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
      </app-link>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)">
 | 
			
		||||
    <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
 | 
			
		||||
      <template slot="title">
 | 
			
		||||
        <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="generateTitle(item.meta.title)" />
 | 
			
		||||
      </template>
 | 
			
		||||
 
 | 
			
		||||
@@ -14,16 +14,21 @@ export default {
 | 
			
		||||
      left: 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    scrollWrapper() {
 | 
			
		||||
      return this.$refs.scrollContainer.$refs.wrap
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    handleScroll(e) {
 | 
			
		||||
      const eventDelta = e.wheelDelta || -e.deltaY * 40
 | 
			
		||||
      const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap
 | 
			
		||||
      const $scrollWrapper = this.scrollWrapper
 | 
			
		||||
      $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
 | 
			
		||||
    },
 | 
			
		||||
    moveToTarget(currentTag) {
 | 
			
		||||
      const $container = this.$refs.scrollContainer.$el
 | 
			
		||||
      const $containerWidth = $container.offsetWidth
 | 
			
		||||
      const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap
 | 
			
		||||
      const $scrollWrapper = this.scrollWrapper
 | 
			
		||||
      const tagList = this.$parent.$refs.tag
 | 
			
		||||
 | 
			
		||||
      let firstTag = null
 | 
			
		||||
@@ -44,6 +49,7 @@ export default {
 | 
			
		||||
        const currentIndex = tagList.findIndex(item => item === currentTag)
 | 
			
		||||
        const prevTag = tagList[currentIndex - 1]
 | 
			
		||||
        const nextTag = tagList[currentIndex + 1]
 | 
			
		||||
 | 
			
		||||
        // the tag's offsetLeft after of nextTag
 | 
			
		||||
        const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
 | 
			
		||||
 | 
			
		||||
@@ -26,7 +26,7 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import ScrollPane from '@/components/ScrollPane'
 | 
			
		||||
import ScrollPane from './ScrollPane'
 | 
			
		||||
import { generateTitle } from '@/utils/i18n'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
 | 
			
		||||
@@ -75,8 +75,10 @@ export default {
 | 
			
		||||
      let tags = []
 | 
			
		||||
      routes.forEach(route => {
 | 
			
		||||
        if (route.meta && route.meta.affix) {
 | 
			
		||||
          const tagPath = path.resolve(basePath, route.path)
 | 
			
		||||
          tags.push({
 | 
			
		||||
            path: path.resolve(basePath, route.path),
 | 
			
		||||
            fullPath: tagPath,
 | 
			
		||||
            path: tagPath,
 | 
			
		||||
            name: route.name,
 | 
			
		||||
            meta: { ...route.meta }
 | 
			
		||||
          })
 | 
			
		||||
@@ -88,7 +90,6 @@ export default {
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      return tags
 | 
			
		||||
    },
 | 
			
		||||
    initTags() {
 | 
			
		||||
@@ -113,12 +114,10 @@ export default {
 | 
			
		||||
        for (const tag of tags) {
 | 
			
		||||
          if (tag.to.path === this.$route.path) {
 | 
			
		||||
            this.$refs.scrollPane.moveToTarget(tag)
 | 
			
		||||
 | 
			
		||||
            // when query is different then update
 | 
			
		||||
            if (tag.to.fullPath !== this.$route.fullPath) {
 | 
			
		||||
              this.$store.dispatch('updateVisitedView', this.$route)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            break
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
@@ -176,8 +175,8 @@ export default {
 | 
			
		||||
      } else {
 | 
			
		||||
        this.left = left
 | 
			
		||||
      }
 | 
			
		||||
      this.top = e.clientY
 | 
			
		||||
 | 
			
		||||
      this.top = e.clientY
 | 
			
		||||
      this.visible = true
 | 
			
		||||
      this.selectedTag = tag
 | 
			
		||||
    },
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
export { default as Navbar } from './Navbar'
 | 
			
		||||
export { default as Sidebar } from './Sidebar/index.vue'
 | 
			
		||||
export { default as TagsView } from './TagsView'
 | 
			
		||||
export { default as TagsView } from './TagsView/index.vue'
 | 
			
		||||
export { default as AppMain } from './AppMain'
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="app-container">
 | 
			
		||||
    <!-- Note that row-key is necessary to get a correct row order. -->
 | 
			
		||||
    <el-table v-loading="listLoading" :data="list" row-key="id" border fit highlight-current-row style="width: 100%">
 | 
			
		||||
    <el-table v-loading="listLoading" ref="dragTable" :data="list" row-key="id" border fit highlight-current-row style="width: 100%">
 | 
			
		||||
 | 
			
		||||
      <el-table-column align="center" label="ID" width="65">
 | 
			
		||||
        <template slot-scope="scope">
 | 
			
		||||
@@ -107,7 +107,7 @@ export default {
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    setSort() {
 | 
			
		||||
      const el = document.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
 | 
			
		||||
      const el = this.$refs.dragTable.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
 | 
			
		||||
      this.sortable = Sortable.create(el, {
 | 
			
		||||
        ghostClass: 'sortable-ghost', // Class name for the drop placeholder,
 | 
			
		||||
        setData: function(dataTransfer) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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,138 +0,0 @@
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
    <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>
 | 
			
		||||
  </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,
 | 
			
		||||
      data:
 | 
			
		||||
        {
 | 
			
		||||
          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: '无'
 | 
			
		||||
                    }
 | 
			
		||||
                  ]
 | 
			
		||||
                }
 | 
			
		||||
              ]
 | 
			
		||||
            }
 | 
			
		||||
          ]
 | 
			
		||||
        },
 | 
			
		||||
      args: [null, null, 'timeLine']
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    message(row) {
 | 
			
		||||
      this.$message.info(row.event)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
@@ -1,129 +0,0 @@
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
    <tree-table :data="data" :columns="columns" border/>
 | 
			
		||||
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
/**
 | 
			
		||||
  Auth: Lei.j1ang
 | 
			
		||||
  Created: 2018/1/19-14:54
 | 
			
		||||
*/
 | 
			
		||||
import treeTable from '@/components/TreeTable'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'TreeTableDemo',
 | 
			
		||||
  components: { treeTable },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      columns: [
 | 
			
		||||
        {
 | 
			
		||||
          text: '事件',
 | 
			
		||||
          value: 'event',
 | 
			
		||||
          width: 200
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'ID',
 | 
			
		||||
          value: 'id'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: '时间线',
 | 
			
		||||
          value: 'timeLine'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: '备注',
 | 
			
		||||
          value: 'comment'
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      data: [
 | 
			
		||||
        {
 | 
			
		||||
          id: 0,
 | 
			
		||||
          event: '事件1',
 | 
			
		||||
          timeLine: 50,
 | 
			
		||||
          comment: '无'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          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: '无'
 | 
			
		||||
                    }
 | 
			
		||||
                  ]
 | 
			
		||||
                }
 | 
			
		||||
              ]
 | 
			
		||||
            }
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										51
									
								
								src/views/tree-table/custom/data.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/views/tree-table/custom/data.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
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
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export default data
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										166
									
								
								src/views/tree-table/custom/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								src/views/tree-table/custom/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,166 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    <div class="app-container">
 | 
			
		||||
 | 
			
		||||
      <el-button type="primary" size="small" style="margin:0 0 20px 0;">
 | 
			
		||||
        <a href="https://github.com/PanJiaChen/vue-element-admin/tree/master/src/components/TreeTable" target="_blank">Documentation</a>
 | 
			
		||||
      </el-button>
 | 
			
		||||
 | 
			
		||||
      <tree-table
 | 
			
		||||
        ref="TreeTable"
 | 
			
		||||
        :data="tableData"
 | 
			
		||||
        :default-expand-all="true"
 | 
			
		||||
        :columns="columns"
 | 
			
		||||
        border
 | 
			
		||||
        default-children="children"
 | 
			
		||||
        @selection-change	="selectChange"
 | 
			
		||||
      >
 | 
			
		||||
 | 
			
		||||
        <template slot="selection">
 | 
			
		||||
          <el-table-column type="selection" align="center" width="55"/>
 | 
			
		||||
        </template>
 | 
			
		||||
 | 
			
		||||
        <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.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>
 | 
			
		||||
 | 
			
		||||
        <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>
 | 
			
		||||
        <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>
 | 
			
		||||
import TreeTable from '@/components/TreeTable'
 | 
			
		||||
import data from './data.js'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  components: { TreeTable },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      tableData: [],
 | 
			
		||||
      tempItem: {},
 | 
			
		||||
      dialogFormVisible: false,
 | 
			
		||||
      columns: [
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Name',
 | 
			
		||||
          key: 'name',
 | 
			
		||||
          expand: true
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Timeline',
 | 
			
		||||
          key: 'timeline'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Append',
 | 
			
		||||
          key: 'append',
 | 
			
		||||
          width: 300
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Operation',
 | 
			
		||||
          key: 'operation',
 | 
			
		||||
          width: 160
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.getData()
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    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', timeLine: this.randomNum() })
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (type === 'brother') {
 | 
			
		||||
        this.$refs.TreeTable.addBrother(row, { name: 'brother', timeLine: this.randomNum() })
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    deleteItem(row) {
 | 
			
		||||
      this.$refs.TreeTable.delete(row)
 | 
			
		||||
    },
 | 
			
		||||
    selectChange(val) {
 | 
			
		||||
      console.log(val)
 | 
			
		||||
    },
 | 
			
		||||
    randomNum() {
 | 
			
		||||
      // return 1~100
 | 
			
		||||
      const max = 100
 | 
			
		||||
      const min = 1
 | 
			
		||||
      return Math.floor(Math.random() * (max - min + 1) + min)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										80
									
								
								src/views/tree-table/data.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/views/tree-table/data.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
 | 
			
		||||
const data = [
 | 
			
		||||
  {
 | 
			
		||||
    id: 0,
 | 
			
		||||
    event: 'Event-0',
 | 
			
		||||
    timeLine: 50
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    id: 1,
 | 
			
		||||
    event: 'Event-1',
 | 
			
		||||
    timeLine: 100,
 | 
			
		||||
    children: [
 | 
			
		||||
      {
 | 
			
		||||
        id: 2,
 | 
			
		||||
        event: 'Event-2',
 | 
			
		||||
        timeLine: 10
 | 
			
		||||
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        id: 3,
 | 
			
		||||
        event: 'Event-3',
 | 
			
		||||
        timeLine: 90,
 | 
			
		||||
        children: [
 | 
			
		||||
          {
 | 
			
		||||
            id: 4,
 | 
			
		||||
            event: 'Event-4',
 | 
			
		||||
            timeLine: 5
 | 
			
		||||
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            id: 5,
 | 
			
		||||
            event: 'Event-5',
 | 
			
		||||
            timeLine: 10
 | 
			
		||||
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            id: 6,
 | 
			
		||||
            event: 'Event-6',
 | 
			
		||||
            timeLine: 75,
 | 
			
		||||
 | 
			
		||||
            children: [
 | 
			
		||||
              {
 | 
			
		||||
                id: 7,
 | 
			
		||||
                event: 'Event-7',
 | 
			
		||||
                timeLine: 50,
 | 
			
		||||
 | 
			
		||||
                children: [
 | 
			
		||||
                  {
 | 
			
		||||
                    id: 71,
 | 
			
		||||
                    event: 'Event-7-1',
 | 
			
		||||
                    timeLine: 25
 | 
			
		||||
 | 
			
		||||
                  },
 | 
			
		||||
                  {
 | 
			
		||||
                    id: 72,
 | 
			
		||||
                    event: 'Event-7-2',
 | 
			
		||||
                    timeLine: 5
 | 
			
		||||
 | 
			
		||||
                  },
 | 
			
		||||
                  {
 | 
			
		||||
                    id: 73,
 | 
			
		||||
                    event: 'Event-7-3',
 | 
			
		||||
                    timeLine: 20
 | 
			
		||||
                  }
 | 
			
		||||
                ]
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                id: 8,
 | 
			
		||||
                event: 'Event-8',
 | 
			
		||||
                timeLine: 25
 | 
			
		||||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export default data
 | 
			
		||||
							
								
								
									
										127
									
								
								src/views/tree-table/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								src/views/tree-table/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,127 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="app-container">
 | 
			
		||||
 | 
			
		||||
    <div style="margin-bottom:20px;">
 | 
			
		||||
 | 
			
		||||
      <el-button type="primary" size="small" 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>
 | 
			
		||||
import treeTable from '@/components/TreeTable'
 | 
			
		||||
import data from './data'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'TreeTableDemo',
 | 
			
		||||
  components: { treeTable },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      defaultExpandAll: false,
 | 
			
		||||
      showCheckbox: true,
 | 
			
		||||
      key: 1,
 | 
			
		||||
      columns: [
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Checkbox',
 | 
			
		||||
          checkbox: true
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          label: '',
 | 
			
		||||
          key: 'id',
 | 
			
		||||
          expand: true
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Event',
 | 
			
		||||
          key: 'event',
 | 
			
		||||
          width: 200,
 | 
			
		||||
          align: 'left'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Scope',
 | 
			
		||||
          key: 'scope'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          label: 'Operation',
 | 
			
		||||
          key: 'operation'
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      data: data
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  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)
 | 
			
		||||
 | 
			
		||||
      const row = scope.row
 | 
			
		||||
      const message = Object.keys(row)
 | 
			
		||||
        .map(i => {
 | 
			
		||||
          return `<p>${i}: ${row[i]}</p>`
 | 
			
		||||
        })
 | 
			
		||||
        .join('')
 | 
			
		||||
 | 
			
		||||
      this.$notify({
 | 
			
		||||
        title: 'Success',
 | 
			
		||||
        dangerouslyUseHTMLString: true,
 | 
			
		||||
        message: message,
 | 
			
		||||
        type: 'success'
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
.option-item{
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  margin-right: 15px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
		Reference in New Issue
	
	Block a user