diff --git a/src/components/TreeTable/README.md b/src/components/TreeTable/README.md new file mode 100644 index 00000000..05326dfa --- /dev/null +++ b/src/components/TreeTable/README.md @@ -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 + +``` + +#### 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 + +``` + +## 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 + +``` + +#### 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 + +``` + +## 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 diff --git a/src/components/TreeTable/eval.js b/src/components/TreeTable/eval.js index d9b89e1c..8659ead8 100644 --- a/src/components/TreeTable/eval.js +++ b/src/components/TreeTable/eval.js @@ -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 +} diff --git a/src/components/TreeTable/index.vue b/src/components/TreeTable/index.vue index a48765c8..9ce7a503 100644 --- a/src/components/TreeTable/index.vue +++ b/src/components/TreeTable/index.vue @@ -1,127 +1,190 @@ - - diff --git a/src/components/TreeTable/readme.md b/src/components/TreeTable/readme.md deleted file mode 100644 index 5b598e11..00000000 --- a/src/components/TreeTable/readme.md +++ /dev/null @@ -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 diff --git a/src/directive/el-table/adaptive.js b/src/directive/el-table/adaptive.js new file mode 100644 index 00000000..3fa29c91 --- /dev/null +++ b/src/directive/el-table/adaptive.js @@ -0,0 +1,42 @@ + +import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event' + +/** + * How to use + * ... + * el-table height is must be set + * bottomOffset: 30(default) // The height of the table from the bottom of the page. + */ + +const doResize = (el, binding, vnode) => { + const { componentInstance: $table } = vnode + + const { value } = binding + + if (!$table.height) { + throw new Error(`el-$table must set the height. Such as height='100px'`) + } + const bottomOffset = (value && value.bottomOffset) || 30 + + if (!$table) return + + const height = window.innerHeight - el.getBoundingClientRect().top - bottomOffset + $table.layout.setHeight(height) + $table.doLayout() +} + +export default { + bind(el, binding, vnode) { + el.resizeListener = () => { + doResize(el, binding, vnode) + } + + addResizeListener(el, el.resizeListener) + }, + inserted(el, binding, vnode) { + doResize(el, binding, vnode) + }, + unbind(el) { + removeResizeListener(el, el.resizeListener) + } +} diff --git a/src/directive/el-table/index.js b/src/directive/el-table/index.js new file mode 100644 index 00000000..d4cf406d --- /dev/null +++ b/src/directive/el-table/index.js @@ -0,0 +1,14 @@ + +import adaptive from './adaptive' + +const install = function(Vue) { + Vue.directive('el-height-adaptive-table', adaptive) +} + +if (window.Vue) { + window['el-height-adaptive-table'] = adaptive + Vue.use(install); // eslint-disable-line +} + +adaptive.install = install +export default adaptive diff --git a/src/directive/waves/waves.js b/src/directive/waves/waves.js index a77f876e..38e07f88 100644 --- a/src/directive/waves/waves.js +++ b/src/directive/waves/waves.js @@ -1,42 +1,73 @@ import './waves.css' -export default{ - bind(el, binding) { - el.addEventListener('click', e => { - const customOpts = Object.assign({}, binding.value) - const opts = Object.assign({ +const context = '@@wavesContext' + +function handleClick(el, binding) { + function handle(e) { + const customOpts = Object.assign({}, binding.value) + const opts = Object.assign( + { ele: el, // 波纹作用元素 type: 'hit', // hit 点击位置扩散 center中心点扩展 color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色 - }, customOpts) - const target = opts.ele - if (target) { - target.style.position = 'relative' - target.style.overflow = 'hidden' - const rect = target.getBoundingClientRect() - let ripple = target.querySelector('.waves-ripple') - if (!ripple) { - ripple = document.createElement('span') - ripple.className = 'waves-ripple' - ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px' - target.appendChild(ripple) - } else { - ripple.className = 'waves-ripple' - } - switch (opts.type) { - case 'center': - ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px' - ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px' - break - default: - ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.documentElement.scrollTop || document.body.scrollTop) + 'px' - ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.documentElement.scrollLeft || document.body.scrollLeft) + 'px' - } - ripple.style.backgroundColor = opts.color - ripple.className = 'waves-ripple z-active' - return false + }, + customOpts + ) + const target = opts.ele + if (target) { + target.style.position = 'relative' + target.style.overflow = 'hidden' + const rect = target.getBoundingClientRect() + let ripple = target.querySelector('.waves-ripple') + if (!ripple) { + ripple = document.createElement('span') + ripple.className = 'waves-ripple' + ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px' + target.appendChild(ripple) + } else { + ripple.className = 'waves-ripple' } - }, false) + switch (opts.type) { + case 'center': + ripple.style.top = rect.height / 2 - ripple.offsetHeight / 2 + 'px' + ripple.style.left = rect.width / 2 - ripple.offsetWidth / 2 + 'px' + break + default: + ripple.style.top = + (e.pageY - rect.top - ripple.offsetHeight / 2 - document.documentElement.scrollTop || + document.body.scrollTop) + 'px' + ripple.style.left = + (e.pageX - rect.left - ripple.offsetWidth / 2 - document.documentElement.scrollLeft || + document.body.scrollLeft) + 'px' + } + ripple.style.backgroundColor = opts.color + ripple.className = 'waves-ripple z-active' + return false + } } + + if (!el[context]) { + el[context] = { + removeHandle: handle + } + } else { + el[context].removeHandle = handle + } + + return handle } +export default { + bind(el, binding) { + el.addEventListener('click', handleClick(el, binding), false) + }, + update(el, binding) { + el.removeEventListener('click', el[context].removeHandle, false) + el.addEventListener('click', handleClick(el, binding), false) + }, + unbind(el) { + el.removeEventListener('click', el[context].removeHandle, false) + el[context] = null + delete el[context] + } +} diff --git a/src/icons/svg/tree-table.svg b/src/icons/svg/tree-table.svg new file mode 100644 index 00000000..8aafdb82 --- /dev/null +++ b/src/icons/svg/tree-table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index d3d10b12..54305b26 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -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 @@ -170,6 +171,7 @@ export const asyncRoutes = [ chartsRouter, nestedRouter, tableRouter, + treeTableRouter, { path: '/example', diff --git a/src/router/modules/table.js b/src/router/modules/table.js index a9c4cb44..4d7f55ef 100644 --- a/src/router/modules/table.js +++ b/src/router/modules/table.js @@ -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'), diff --git a/src/router/modules/tree-table.js b/src/router/modules/tree-table.js new file mode 100644 index 00000000..5ee26828 --- /dev/null +++ b/src/router/modules/tree-table.js @@ -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 diff --git a/src/styles/sidebar.scss b/src/styles/sidebar.scss index 96e89be7..03449706 100644 --- a/src/styles/sidebar.scss +++ b/src/styles/sidebar.scss @@ -83,19 +83,26 @@ .hideSidebar { .sidebar-container { - width: 36px !important; + width: 54px !important; } .main-container { - margin-left: 36px; + margin-left: 54px; + } + + .svg-icon { + margin-right: 0px; } .submenu-title-noDropdown { - padding-left: 10px !important; + padding: 0 !important; position: relative; .el-tooltip { - padding: 0 10px !important; + padding: 0 !important; + .svg-icon { + margin-left: 20px; + } } } @@ -103,7 +110,10 @@ overflow: hidden; &>.el-submenu__title { - padding-left: 10px !important; + padding: 0 !important; + .svg-icon { + margin-left: 20px; + } .el-submenu__icon-arrow { display: none; diff --git a/src/styles/variables.scss b/src/styles/variables.scss index 50d9b3ef..98d7b672 100644 --- a/src/styles/variables.scss +++ b/src/styles/variables.scss @@ -19,9 +19,10 @@ $menuHover:#263445; $subMenuBg:#1f2d3d; $subMenuHover:#001528; -$sideBarWidth: 180px; +$sideBarWidth: 210px; // the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass :export { menuText: $menuText; menuActiveText: $menuActiveText; diff --git a/src/utils/index.js b/src/utils/index.js index 1370a423..ebe58ff8 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -91,20 +91,19 @@ export function getQueryObject(url) { } /** - *get getByteLen - * @param {Sting} val input value + * @param {Sting} input value * @returns {number} output value */ -export function getByteLen(val) { - let len = 0 - for (let i = 0; i < val.length; i++) { - if (val[i].match(/[^\x00-\xff]/gi) != null) { - len += 1 - } else { - len += 0.5 - } +export function byteLength(str) { + // returns the byte length of an utf8 string + let s = str.length + for (var i = str.length - 1; i >= 0; i--) { + const code = str.charCodeAt(i) + if (code > 0x7f && code <= 0x7ff) s++ + else if (code > 0x7ff && code <= 0xffff) s += 2 + if (code >= 0xDC00 && code <= 0xDFFF) i-- } - return Math.floor(len) + return s } export function cleanArray(actual) { @@ -137,7 +136,8 @@ export function param2Obj(url) { decodeURIComponent(search) .replace(/"/g, '\\"') .replace(/&/g, '","') - .replace(/=/g, '":"') + + .replace(/=/g, '":"') + .replace(/\+/g, ' ') + '"}' ) } diff --git a/src/views/layout/components/Sidebar/SidebarItem.vue b/src/views/layout/components/Sidebar/SidebarItem.vue index 94275aa8..47ac4b4d 100644 --- a/src/views/layout/components/Sidebar/SidebarItem.vue +++ b/src/views/layout/components/Sidebar/SidebarItem.vue @@ -9,7 +9,7 @@ - + diff --git a/src/views/layout/components/Sidebar/index.vue b/src/views/layout/components/Sidebar/index.vue index 93c044af..5a81e84f 100644 --- a/src/views/layout/components/Sidebar/index.vue +++ b/src/views/layout/components/Sidebar/index.vue @@ -6,6 +6,7 @@ :background-color="variables.menuBg" :text-color="variables.menuText" :active-text-color="variables.menuActiveText" + :collapse-transition="false" mode="vertical" > diff --git a/src/components/ScrollPane/index.vue b/src/views/layout/components/TagsView/ScrollPane.vue similarity index 91% rename from src/components/ScrollPane/index.vue rename to src/views/layout/components/TagsView/ScrollPane.vue index 172afccc..820a536e 100644 --- a/src/components/ScrollPane/index.vue +++ b/src/views/layout/components/TagsView/ScrollPane.vue @@ -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 diff --git a/src/views/layout/components/TagsView.vue b/src/views/layout/components/TagsView/index.vue similarity index 97% rename from src/views/layout/components/TagsView.vue rename to src/views/layout/components/TagsView/index.vue index 25b8d45d..72e127f2 100644 --- a/src/views/layout/components/TagsView.vue +++ b/src/views/layout/components/TagsView/index.vue @@ -26,7 +26,7 @@ diff --git a/src/views/table/treeTable/treeTable.vue b/src/views/table/treeTable/treeTable.vue deleted file mode 100644 index d2ecf14d..00000000 --- a/src/views/table/treeTable/treeTable.vue +++ /dev/null @@ -1,129 +0,0 @@ - - - diff --git a/src/views/tree-table/custom/data.js b/src/views/tree-table/custom/data.js new file mode 100644 index 00000000..020f6247 --- /dev/null +++ b/src/views/tree-table/custom/data.js @@ -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 + diff --git a/src/views/tree-table/custom/index.vue b/src/views/tree-table/custom/index.vue new file mode 100644 index 00000000..11e47912 --- /dev/null +++ b/src/views/tree-table/custom/index.vue @@ -0,0 +1,157 @@ + + + diff --git a/src/views/tree-table/data.js b/src/views/tree-table/data.js new file mode 100644 index 00000000..67b0137a --- /dev/null +++ b/src/views/tree-table/data.js @@ -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 diff --git a/src/views/tree-table/index.vue b/src/views/tree-table/index.vue new file mode 100644 index 00000000..2e131157 --- /dev/null +++ b/src/views/tree-table/index.vue @@ -0,0 +1,127 @@ + + + + +