Compare commits

...

3 Commits

Author SHA1 Message Date
Pan
d431de0589 perf keep-alive in nested route 2018-01-24 16:34:01 +08:00
Pan
6f2a7ce804 feat[menu]: add alwaysShow option 2018-01-24 14:47:20 +08:00
Zenon
2e0d3fd0e4 修改treeTable相关 (#422)
* 1.删除无用的属性
2.修改readme
3.修改eval.js,给后两个参数设置默认值

* update readme
2018-01-24 10:33:05 +08:00
10 changed files with 74 additions and 41 deletions

View File

@@ -4,7 +4,7 @@
*/ */
'use strict' 'use strict'
import Vue from 'vue' import Vue from 'vue'
export default function treeToArray(data, expandedAll, parent, level) { export default function treeToArray(data, expandedAll, parent = null, level = null) {
let tmp = [] let tmp = []
Array.from(data).forEach(function(record) { Array.from(data).forEach(function(record) {
if (record._expanded === undefined) { if (record._expanded === undefined) {

View File

@@ -33,7 +33,6 @@ import treeToArray from './eval'
export default { export default {
name: 'treeTable', name: 'treeTable',
props: { props: {
a: 1,
data: { data: {
type: [Array, Object], type: [Array, Object],
required: true required: true

View File

@@ -1,8 +1,8 @@
## 写在前面 ## 写在前面
此组件仅提供一个创建TreeTable的解决方案 此组件仅提供一个创建TreeTable的解决思路
## prop说明 ## prop说明
### data #### *data*
**必填** **必填**
原始数据,要求是一个数组或者对象 原始数据,要求是一个数组或者对象
@@ -35,13 +35,16 @@
} }
``` ```
### columns #### columns
列属性,要求是一个数组 列属性,要求是一个数组
1. text: 显示在表头 1. text: 显示在表头的文字
2. value: 对应data的keytreeTable将显示相应的value 2. value: 对应data的keytreeTable将显示相应的value
3. width: 每列的宽度,为一个数字 3. width: 每列的宽度,为一个数字(可选)
如果你想要每个字段都有自定义的样式或者嵌套其他组件columns可不提供直接像在el-table一样写即可如果没有自定义内容提供columns将更加的便捷方便 如果你想要每个字段都有自定义的样式或者嵌套其他组件columns可不提供直接像在el-table一样写即可如果没有自定义内容提供columns将更加的便捷方便
如果你有几个字段是需要自定义的几个不需要那么可以将不需要自定义的字段放入columns将需要自定义的内容放入到slot中详情见后文
```javascript ```javascript
[{ [{
value:string, value:string,
@@ -54,25 +57,33 @@
}] }]
``` ```
### expandAll #### expandAll
是否默认全部展开boolean值默认为false 是否默认全部展开boolean值默认为false
### evalFunc #### evalFunc
解析函数function非必须 解析函数function非必须
如果不提供将使用默认的evalFunc 如果不提供,将使用默认的[evalFunc](./eval.js)
如果提供了evalFunc,那么会用提供的evalFunc去解析data并返回treeTable渲染所需要的值。如何编写一个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/example/table/treeTable/customEval.js)
### evalArgs #### evalArgs
解析函数的参数,是一个数组 解析函数的参数,是一个数组
**请注意自定义的解析函数参数第一个为this.data你不需要在evalArgs填写。** **请注意自定义的解析函数参数第一个为this.data你不需要在evalArgs填写。** *this.data为需要解析的数据*
如你的解析函数需要的参数为`(this.data,1,2,3,4)`,那么你只需要将`[1,2,3,4]`赋值给`evalArgs`就可以了 如你的解析函数需要的参数为`(this.data,1,2,3,4)`,那么你只需要将`[1,2,3,4]`赋值给`evalArgs`就可以了
如果你的解析函数参数只有一个`(this.data)`,那么就可以不用填写evalArgs了
具体可参考[*customEval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/example/table/treeTable/customEval.js)的函数参数和[customTreeTable](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/example/table/treeTable/customTreeTable.vue)的`evalArgs`属性值
## slot ## slot
请参考`customTreeTable` 这是一个自定义列的插槽。
默认情况下treeTable只有一行行展示数据的功能。但是一般情况下我们会要给行加上一个操作按钮或者根据当行数据展示不同的样式这时我们就需要自定义列了。请参考[customTreeTable](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/example/table/treeTable/customTreeTable.vue)[实例效果](http://panjiachen.github.io/vue-element-admin/#/example/table/custom-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

View File

@@ -42,7 +42,8 @@ export default {
exportExcel: 'Export Excel', exportExcel: 'Export Excel',
selectExcel: 'Export Selected', selectExcel: 'Export Selected',
uploadExcel: 'Upload Excel', uploadExcel: 'Upload Excel',
exportZip: 'Zip', zip: 'Zip',
exportZip: 'Export Zip',
theme: 'Theme', theme: 'Theme',
clipboardDemo: 'Clipboard', clipboardDemo: 'Clipboard',
i18n: 'I18n' i18n: 'I18n'

View File

@@ -24,10 +24,10 @@ export default {
mixChart: '混合图表', mixChart: '混合图表',
example: '综合实例', example: '综合实例',
Table: 'Table', Table: 'Table',
dynamicTable: '动态table', dynamicTable: '动态Table',
dragTable: '拖拽table', dragTable: '拖拽Table',
inlineEditTable: 'table内编辑', inlineEditTable: 'Table内编辑',
complexTable: '综合table', complexTable: '综合Table',
treeTable: '树形表格', treeTable: '树形表格',
customTreeTable: '自定义树表', customTreeTable: '自定义树表',
tab: 'Tab', tab: 'Tab',
@@ -38,13 +38,14 @@ export default {
page401: '401', page401: '401',
page404: '404', page404: '404',
errorLog: '错误日志', errorLog: '错误日志',
excel: 'excel', excel: 'Excel',
exportExcel: 'export excel', exportExcel: 'Export Excel',
selectExcel: 'export selected', selectExcel: 'Export Selected',
uploadExcel: 'upload excel', uploadExcel: 'Upload Excel',
exportZip: 'zip', zip: 'Zip',
exportZip: 'Export Zip',
theme: '换肤', theme: '换肤',
clipboardDemo: 'clipboard', clipboardDemo: 'Clipboard',
i18n: '国际化' i18n: '国际化'
}, },
navbar: { navbar: {

View File

@@ -15,6 +15,9 @@ import Layout from '../views/layout/Layout'
/** /**
* hidden: true if `hidden:true` will not show in the sidebar(default is false) * hidden: true if `hidden:true` will not show in the sidebar(default is false)
* alwaysShow: true if set true, will always show the root menu, whatever its child routes length
* if not set alwaysShow, only more than one route under the children
* it will becomes nested mode, otherwise not show the root menu
* redirect: noredirect if `redirect:noredirect` will no redirct in the breadcrumb * redirect: noredirect if `redirect:noredirect` will no redirct in the breadcrumb
* name:'router-name' the name is used by <keep-alive> (must set!!!) * name:'router-name' the name is used by <keep-alive> (must set!!!)
* meta : { * meta : {
@@ -217,7 +220,9 @@ export const asyncRouterMap = [
path: '/zip', path: '/zip',
component: Layout, component: Layout,
redirect: '/zip/download', redirect: '/zip/download',
children: [{ path: 'download', component: _import('zip/index'), name: 'exportZip', meta: { title: 'exportZip', icon: 'zip' }}] alwaysShow: true,
meta: { title: 'zip', icon: 'zip' },
children: [{ path: 'download', component: _import('zip/index'), name: 'exportZip', meta: { title: 'exportZip' }}]
}, },
{ {

View File

@@ -6,14 +6,21 @@ const tagsView = {
mutations: { mutations: {
ADD_VISITED_VIEWS: (state, view) => { ADD_VISITED_VIEWS: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push({
name: view.name, if (view.showInVisitedViews) {
path: view.path, state.visitedViews.push({
title: view.meta.title || 'no-name' name: view.name,
}) path: view.path,
if (!view.meta.noCache) { title: view.meta.title || 'no-name'
state.cachedViews.push(view.name) })
} }
if (!view.meta.noCache) {
const cachedViews = [...state.cachedViews]
cachedViews.push(view.name)
state.cachedViews = Array.from(new Set([...cachedViews]))
}
console.log(state.cachedViews)
}, },
DEL_VISITED_VIEWS: (state, view) => { DEL_VISITED_VIEWS: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) { for (const [i, v] of state.visitedViews.entries()) {

View File

@@ -8,7 +8,7 @@
<script> <script>
export default { export default {
name: 'TableMain', name: 'Table',
computed: { computed: {
cachedViews() { cachedViews() {
return this.$store.state.tagsView.cachedViews return this.$store.state.tagsView.cachedViews

View File

@@ -2,7 +2,7 @@
<div class="menu-wrapper"> <div class="menu-wrapper">
<template v-for="item in routes" v-if="!item.hidden&&item.children"> <template v-for="item in routes" v-if="!item.hidden&&item.children">
<router-link v-if="item.children.length===1 && !item.children[0].children" :to="item.path+'/'+item.children[0].path" :key="item.children[0].name"> <router-link v-if="item.children.length===1 && !item.children[0].children&&!item.alwaysShow" :to="item.path+'/'+item.children[0].path" :key="item.children[0].name">
<el-menu-item :index="item.path+'/'+item.children[0].path" :class="{'submenu-title-noDropdown':!isNest}"> <el-menu-item :index="item.path+'/'+item.children[0].path" :class="{'submenu-title-noDropdown':!isNest}">
<svg-icon v-if="item.children[0].meta&&item.children[0].meta.icon" :icon-class="item.children[0].meta.icon"></svg-icon> <svg-icon v-if="item.children[0].meta&&item.children[0].meta.icon" :icon-class="item.children[0].meta.icon"></svg-icon>
<span v-if="item.children[0].meta&&item.children[0].meta.title">{{generateTitle(item.children[0].meta.title)}}</span> <span v-if="item.children[0].meta&&item.children[0].meta.title">{{generateTitle(item.children[0].meta.title)}}</span>

View File

@@ -52,8 +52,11 @@ export default {
methods: { methods: {
generateTitle, // generateTitle by vue-i18n generateTitle, // generateTitle by vue-i18n
generateRoute() { generateRoute() {
if (this.$route.name) { let matched = [...this.$route.matched]
return this.$route matched.splice(0, 1)
matched = matched.filter(item => item.name)
if (matched) {
return matched
} }
return false return false
}, },
@@ -61,11 +64,17 @@ export default {
return route.path === this.$route.path || route.name === this.$route.name return route.path === this.$route.path || route.name === this.$route.name
}, },
addViewTags() { addViewTags() {
const route = this.generateRoute() const routes = this.generateRoute()
if (!route) { if (!routes) {
return false return false
} }
this.$store.dispatch('addVisitedViews', route) const length = routes.length
routes.forEach((item, index) => {
if (index === length - 1) {
item.showInVisitedViews = true
}
this.$store.dispatch('addVisitedViews', item)
})
}, },
moveToCurrentTag() { moveToCurrentTag() {
const tags = this.$refs.tag const tags = this.$refs.tag