From 6255f54f413ae9784d9bfb94151b59aeca72c0ec Mon Sep 17 00:00:00 2001 From: kaisawind Date: Fri, 1 Mar 2019 18:44:37 +0800 Subject: [PATCH 1/8] fix[TagsView]: fixed refresh affixed-tag bug (#1653) --- src/views/layout/components/TagsView.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/layout/components/TagsView.vue b/src/views/layout/components/TagsView.vue index cfac9c7d..7b7be8f7 100644 --- a/src/views/layout/components/TagsView.vue +++ b/src/views/layout/components/TagsView.vue @@ -76,6 +76,7 @@ export default { routes.forEach(route => { if (route.meta && route.meta.affix) { tags.push({ + fullPath: path.resolve(basePath, route.path), path: path.resolve(basePath, route.path), name: route.name, meta: { ...route.meta } From aa2eb7d40f1e64bfaf3a0ee1d0dd5a0a6d161dee Mon Sep 17 00:00:00 2001 From: MaYuanhai <414199639@qq.com> Date: Mon, 4 Mar 2019 10:54:58 +0800 Subject: [PATCH 2/8] perf[utils.js]: refactor byteLength function (#1650) --- src/utils/index.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/utils/index.js b/src/utils/index.js index 1370a423..fbcb4602 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) { From 1e06f1da67ed090c74ffa85ceb17c6217ae7a55c Mon Sep 17 00:00:00 2001 From: Pan Date: Mon, 4 Mar 2019 11:43:14 +0800 Subject: [PATCH 3/8] perf[TagsView]: refine code --- src/views/layout/components/TagsView.vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/views/layout/components/TagsView.vue b/src/views/layout/components/TagsView.vue index 7b7be8f7..66059816 100644 --- a/src/views/layout/components/TagsView.vue +++ b/src/views/layout/components/TagsView.vue @@ -75,9 +75,10 @@ export default { let tags = [] routes.forEach(route => { if (route.meta && route.meta.affix) { + const tagPath = path.resolve(basePath, route.path) tags.push({ - fullPath: path.resolve(basePath, route.path), - path: path.resolve(basePath, route.path), + fullPath: tagPath, + path: tagPath, name: route.name, meta: { ...route.meta } }) From 96774060020a2d80436faf08dd1089fae5a17ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8A=B1=E8=A3=A4=E8=A1=A9?= Date: Tue, 5 Mar 2019 13:20:30 +0800 Subject: [PATCH 4/8] perf[TagsView]: set the scrollPane as a business component (#1660) --- .../layout/components/TagsView/ScrollPane.vue} | 10 ++++++++-- .../components/{TagsView.vue => TagsView/index.vue} | 7 ++----- src/views/layout/components/index.js | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) rename src/{components/ScrollPane/index.vue => views/layout/components/TagsView/ScrollPane.vue} (91%) rename src/views/layout/components/{TagsView.vue => TagsView/index.vue} (99%) 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 99% rename from src/views/layout/components/TagsView.vue rename to src/views/layout/components/TagsView/index.vue index 66059816..53d592bc 100644 --- a/src/views/layout/components/TagsView.vue +++ b/src/views/layout/components/TagsView/index.vue @@ -26,7 +26,7 @@ - - diff --git a/src/components/TreeTable/readme.md b/src/components/TreeTable/readme.md index 5b598e11..fe404ed0 100644 --- a/src/components/TreeTable/readme.md +++ b/src/components/TreeTable/readme.md @@ -1,89 +1,99 @@ ## 写在前面 -此组件仅提供一个创建TreeTable的解决思路 -## prop说明 -#### *data* - **必填** +此组件仅提供一个创建 TreeTable 的解决思路,本组件充分利用 vue 插槽的特性,方便用户自定义 - 原始数据,要求是一个数组或者对象 - ```javascript - [{ - key1: value1, - key2: value2, - children: [{ +evel.js 里面 `addAttrs` 方法会给数据添加几个属性,treeTotable 会对数组扁平化。这些操作都不会破坏源数据,只是会新增属性。 + +调用 addAttrs 后,因\_\_parent 属性,会造成数据循环引用,使用 JSON.stringify()报错,所以转成 JSON 之前需要清除\_\_parent 属性。 + +## prop 说明 + +- data(原始数据,要求是一个数组或者对象) +- columns(列属性,要求是一个数组) +- renderContent(数组扁平化方法(可选)) +- defaultExpandAll(默认是否全部展开,默认全部展开) +- defaultChildren(子元素名,默认为 children) +- spreadOffset(扩展符号的偏移量,默认为 50px) +- checkboxOffset(复选框的偏移量,默认为 50px) + +--- + +### 代码示例 + +- data(**必填**) + +原始数据, + +```js +const data = [ + { + key1: value1, + key2: value2, + children: [ + { key1: value1 }, { key1: value1 - }] - }, - { - key1: value1 - }] - ``` - 或者 - ```javascript - { - key1: value1, - key2: value2, - children: [{ - key1: value1 - }, - { - key1: value1 - }] - } - ``` + } + ] + }, + { + key1: value1 + } +] +``` -#### columns - 列属性,要求是一个数组 +或者 - 1. text: 显示在表头的文字 - 2. value: 对应data的key。treeTable将显示相应的value - 3. width: 每列的宽度,为一个数字(可选) +```javascript + { + key1: value1, + key2: value2, + children: [{ + key1: value1 + }, + { + key1: value1 + }] + } +``` - 如果你想要每个字段都有自定义的样式或者嵌套其他组件,columns可不提供,直接像在el-table一样写即可,如果没有自定义内容,提供columns将更加的便捷方便 +- columns - 如果你有几个字段是需要自定义的,几个不需要,那么可以将不需要自定义的字段放入columns,将需要自定义的内容放入到slot中,详情见后文 - ```javascript - [{ - value:string, - text:string, - width:number - },{ - value:string, - text:string, - width:number - }] - ``` +1. label: 显示在表头的文字 +2. key: 对应 data 的 key。treeTable 将显示相应的 value +3. width: 每列的宽度,为一个数字(可选) -#### expandAll - 是否默认全部展开,boolean值,默认为false +树表组件将会根据 columns 的 key 属性生成具名插槽,如果你需要对列数据进行自定义,通过插槽即可实现 -#### evalFunc - 解析函数,function,非必须 +```javascript +const columns = [ + // 建议第一列做展开收缩操作 + { label: '', key: '__spread', width: '200' }, + // 如果添加复选框 + { label: '', key: '__checkbox', width: '200' }, + { + label: string, + key: string, + width: number + }, + { + label: string, + key: string, + width: number + } +] +``` - 如果不提供,将使用默认的[evalFunc](./eval.js) +#### renderContent - 如果提供了evalFunc,那么会用提供的evalFunc去解析data,并返回treeTable渲染所需要的值。如何编写一个evalFunc,请参考[*eval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/components/TreeTable/eval.js)或[*customEval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customEval.js) +解析函数,function,非必须 -#### evalArgs - 解析函数的参数,是一个数组 +如果不提供,将使用默认的[evalFunc](./eval.js) - **请注意,自定义的解析函数参数第一个为this.data,第二个参数为, this.expandAll,你不需要在evalArgs填写。一定记住,这两个参数是强制性的,并且位置不可颠倒** *this.data为需要解析的数据,this.expandAll为是否默认展开* +如果提供了 evalFunc,那么会用提供的 evalFunc 去解析 data,并返回 treeTable 渲染所需要的值。 - 如你的解析函数需要的参数为`(this.data, this.expandAll,1,2,3,4)`,那么你只需要将`[1,2,3,4]`赋值给`evalArgs`就可以了 +## 其他 - 如果你的解析函数参数只有`(this.data, this.expandAll)`,那么就可以不用填写evalArgs了 - - 具体可参考[*customEval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customEval.js)的函数参数和[customTreeTable](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customTreeTable.vue)的`evalArgs`属性值 - - ## slot - 这是一个自定义列的插槽。 - - 默认情况下,treeTable只有一行行展示数据的功能。但是一般情况下,我们会要给行加上一个操作按钮或者根据当行数据展示不同的样式,这时我们就需要自定义列了。请参考[customTreeTable](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customTreeTable.vue),[实例效果](https://panjiachen.github.io/vue-element-admin/#/table/tree-table) - - `slot`和`columns属性`可同时存在,columns里面的数据列会在slot自定义列的左边展示 - - ## 其他 - 如果有其他的需求,请参考[el-table](http://element-cn.eleme.io/#/en-US/component/table)的api自行修改index.vue +如果有其他的需求,请参考[el-table](http://element-cn.eleme.io/#/en-US/component/table)的 api 自行修改 index.vue diff --git a/src/mock/table.js b/src/mock/table.js new file mode 100644 index 00000000..e69de29b diff --git a/src/views/table/treeTable/customEval.js b/src/views/table/treeTable/customEval.js deleted file mode 100644 index 73badb68..00000000 --- a/src/views/table/treeTable/customEval.js +++ /dev/null @@ -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 -} diff --git a/src/views/table/treeTable/customTreeTable.vue b/src/views/table/treeTable/customTreeTable.vue index 2a216171..1ed346fb 100644 --- a/src/views/table/treeTable/customTreeTable.vue +++ b/src/views/table/treeTable/customTreeTable.vue @@ -1,137 +1,162 @@