vue2-client 1.2.38 → 1.2.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,198 +1,201 @@
1
- <template>
2
- <common-layout>
3
- <div class="top">
4
- <div class="header">
5
- <img alt="logo" class="logo" src="@/assets/img/logo.png" />
6
- <span class="title">{{ systemName }}</span>
7
- </div>
8
- <div class="desc">为PC端中、后台系统业务开发提供支持</div>
9
- </div>
10
- <div class="login">
11
- <a-form @submit="onSubmit" :form="form">
12
- <a-tabs size="large" :tabBarStyle="{textAlign: 'center'}" style="padding: 0 2px;">
13
- <a-tab-pane tab="账户密码登录" key="1">
14
- <a-alert
15
- type="error"
16
- :closable="true"
17
- v-show="error"
18
- :message="error"
19
- showIcon
20
- style="margin-bottom: 24px;" />
21
- <a-form-item>
22
- <a-input
23
- autocomplete="autocomplete"
24
- size="large"
25
- placeholder="admin"
26
- v-decorator="['name', {rules: [{ required: true, message: '请输入账户名', whitespace: true}]}]"
27
- >
28
- <a-icon slot="prefix" type="user" />
29
- </a-input>
30
- </a-form-item>
31
- <a-form-item>
32
- <a-input
33
- size="large"
34
- placeholder="888888"
35
- autocomplete="autocomplete"
36
- type="password"
37
- v-decorator="['password', {rules: [{ required: true, message: '请输入密码', whitespace: true}]}]"
38
- >
39
- <a-icon slot="prefix" type="lock" />
40
- </a-input>
41
- </a-form-item>
42
- </a-tab-pane>
43
- </a-tabs>
44
- <div>
45
- <a-checkbox :checked="true" >自动登录</a-checkbox>
46
- </div>
47
- <a-form-item>
48
- <a-button :loading="logging" style="width: 100%;margin-top: 24px" size="large" htmlType="submit" type="primary">登录</a-button>
49
- </a-form-item>
50
- </a-form>
51
- </div>
52
- </common-layout>
53
- </template>
54
-
55
- <script>
56
- import CommonLayout from '@vue2-client/layouts/CommonLayout'
57
- import { getRoutesConfig, login } from '@vue2-client/services/user'
58
- import { setAuthorization } from '@vue2-client/utils/request'
59
- import { loadRoutes, funcToRouter } from '@vue2-client/utils/routerUtil'
60
- import { mapMutations } from 'vuex'
61
- import JSEncrypt from 'jsencrypt'
62
- import { ACCESS_TOKEN } from '@vue2-client/store/mutation-types'
63
- import Vue from 'vue'
64
- import { positions } from '@vue2-client/mock/common'
65
- import { timeFix } from '@vue2-client/utils/util'
66
- const { homePage, ticketPage } = require('@vue2-client/config')
67
- // import { router } from '@vue2-client/mock/user/routes'
68
-
69
- export default {
70
- name: 'Login',
71
- components: { CommonLayout },
72
- data () {
73
- return {
74
- logging: false,
75
- error: '',
76
- form: this.$form.createForm(this)
77
- }
78
- },
79
- computed: {
80
- systemName () {
81
- return this.$store.state.setting.systemName
82
- }
83
- },
84
- methods: {
85
- ...mapMutations('account', ['setUser', 'setPermissions', 'setRoles']),
86
- onSubmit (e) {
87
- e.preventDefault()
88
- this.form.validateFields((err) => {
89
- if (!err) {
90
- this.logging = true
91
- const name = this.form.getFieldValue('name')
92
- const password = this.form.getFieldValue('password')
93
- login(name, password).then(this.afterLogin)
94
- }
95
- })
96
- },
97
- afterLogin (res) {
98
- const name = this.form.getFieldValue('name')
99
- const password = this.form.getFieldValue('password')
100
- this.logging = false
101
- const loginRes = res.states
102
- if (loginRes === '登录成功') {
103
- const encrypt = new JSEncrypt()
104
- encrypt.setPublicKey('MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqPvovSfXcwBbW8cKMCgwqNpsYuzF8RPAPFb7LGsnVo44JhM/xxzDyzoYtdfNmtbIuKVi9PzIsyp6rg+09gbuI6UGwBZ5DWBDBMqv5MPdOF5dCQkB2Bbr5yPfURPENypUz+pBFBg41d+BC+rwRiXELwKy7Y9caD/MtJyHydj8OUwIDAQAB')
105
- const data = encrypt.encrypt(JSON.stringify({ username: name, password: password }))
106
- localStorage.setItem(ACCESS_TOKEN, data)
107
- // 获取路由配置
108
- getRoutesConfig(data).then(result => {
109
- Vue.$login.login(result).then(() => {
110
- const user = Object.assign({
111
- username: result.ename,
112
- name: result.name,
113
- avatar: 'https://gw.alipayobjects.com/zos/rmsportal/jZUIxmJycoymBprLOUbT.png',
114
- address: '西安市',
115
- position: positions[0]
116
- }, result)
117
- this.setUser(user)
118
- this.setPermissions([{ id: 'queryForm', operation: ['add', 'edit'] }])
119
- this.setRoles([{ id: 'admin', operation: ['add', 'edit', 'delete'] }])
120
- let timestamp = new Date().getTime()// 当前的时间戳
121
- timestamp = timestamp + 60 * 60 * 1000
122
- // 格式化时间获取年月日, 登陆过期时间
123
- const dateAfter = new Date(timestamp)
124
- setAuthorization({ token: data, expireAt: dateAfter })
125
- loadRoutes(funcToRouter(user.functions))
126
- if (result.deps === '用户工单登记') {
127
- this.$router.push(ticketPage).catch(() => {})
128
- } else {
129
- this.$router.push(homePage).catch(() => {})
130
- }
131
- this.$message.success(timeFix().CN + ',欢迎回来', 3)
132
- })
133
- })
134
- } else {
135
- this.error = loginRes
136
- }
137
- }
138
- }
139
- }
140
- </script>
141
-
142
- <style lang="less" scoped>
143
- .common-layout{
144
- .top {
145
- text-align: center;
146
- .header {
147
- height: 44px;
148
- line-height: 44px;
149
- a {
150
- text-decoration: none;
151
- }
152
- .logo {
153
- height: 44px;
154
- vertical-align: top;
155
- margin-right: 16px;
156
- }
157
- .title {
158
- font-size: 33px;
159
- color: @title-color;
160
- font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif;
161
- font-weight: 600;
162
- position: relative;
163
- top: 2px;
164
- }
165
- }
166
- .desc {
167
- font-size: 14px;
168
- color: @text-color-second;
169
- margin-top: 12px;
170
- margin-bottom: 40px;
171
- }
172
- }
173
- .login{
174
- width: 368px;
175
- margin: 0 auto;
176
- @media screen and (max-width: 576px) {
177
- width: 95%;
178
- }
179
- @media screen and (max-width: 320px) {
180
- .captcha-button{
181
- font-size: 14px;
182
- }
183
- }
184
- .icon {
185
- font-size: 24px;
186
- color: @text-color-second;
187
- margin-left: 16px;
188
- vertical-align: middle;
189
- cursor: pointer;
190
- transition: color 0.3s;
191
-
192
- &:hover {
193
- color: @primary-color;
194
- }
195
- }
196
- }
197
- }
198
- </style>
1
+ <template>
2
+ <common-layout>
3
+ <div class="top">
4
+ <div class="header">
5
+ <img alt="logo" class="logo" src="@/assets/img/logo.png" />
6
+ <span class="title">{{ systemName }}</span>
7
+ </div>
8
+ <div class="desc">{{ systemDesc }}</div>
9
+ </div>
10
+ <div class="login">
11
+ <a-form @submit="onSubmit" :form="form">
12
+ <a-tabs size="large" :tabBarStyle="{textAlign: 'center'}" style="padding: 0 2px;">
13
+ <a-tab-pane tab="账户密码登录" key="1">
14
+ <a-alert
15
+ type="error"
16
+ :closable="true"
17
+ v-show="error"
18
+ :message="error"
19
+ showIcon
20
+ style="margin-bottom: 24px;" />
21
+ <a-form-item>
22
+ <a-input
23
+ autocomplete="autocomplete"
24
+ size="large"
25
+ placeholder="admin"
26
+ v-decorator="['name', {rules: [{ required: true, message: '请输入账户名', whitespace: true}]}]"
27
+ >
28
+ <a-icon slot="prefix" type="user" />
29
+ </a-input>
30
+ </a-form-item>
31
+ <a-form-item>
32
+ <a-input
33
+ size="large"
34
+ placeholder="888888"
35
+ autocomplete="autocomplete"
36
+ type="password"
37
+ v-decorator="['password', {rules: [{ required: true, message: '请输入密码', whitespace: true}]}]"
38
+ >
39
+ <a-icon slot="prefix" type="lock" />
40
+ </a-input>
41
+ </a-form-item>
42
+ </a-tab-pane>
43
+ </a-tabs>
44
+ <div>
45
+ <a-checkbox :checked="true" >自动登录</a-checkbox>
46
+ </div>
47
+ <a-form-item>
48
+ <a-button :loading="logging" style="width: 100%;margin-top: 24px" size="large" htmlType="submit" type="primary">登录</a-button>
49
+ </a-form-item>
50
+ </a-form>
51
+ </div>
52
+ </common-layout>
53
+ </template>
54
+
55
+ <script>
56
+ import CommonLayout from '@vue2-client/layouts/CommonLayout'
57
+ import { getRoutesConfig, login } from '@vue2-client/services/user'
58
+ import { setAuthorization } from '@vue2-client/utils/request'
59
+ import { loadRoutes, funcToRouter } from '@vue2-client/utils/routerUtil'
60
+ import { mapMutations } from 'vuex'
61
+ import JSEncrypt from 'jsencrypt'
62
+ import { ACCESS_TOKEN } from '@vue2-client/store/mutation-types'
63
+ import Vue from 'vue'
64
+ import { positions } from '@vue2-client/mock/common'
65
+ import { timeFix } from '@vue2-client/utils/util'
66
+ const { homePage, ticketPage } = require('@vue2-client/config')
67
+ // import { router } from '@vue2-client/mock/user/routes'
68
+
69
+ export default {
70
+ name: 'Login',
71
+ components: { CommonLayout },
72
+ data () {
73
+ return {
74
+ logging: false,
75
+ error: '',
76
+ form: this.$form.createForm(this)
77
+ }
78
+ },
79
+ computed: {
80
+ systemName () {
81
+ return this.$store.state.setting.systemName
82
+ },
83
+ systemDesc () {
84
+ return this.$store.state.setting.systemDesc
85
+ }
86
+ },
87
+ methods: {
88
+ ...mapMutations('account', ['setUser', 'setPermissions', 'setRoles']),
89
+ onSubmit (e) {
90
+ e.preventDefault()
91
+ this.form.validateFields((err) => {
92
+ if (!err) {
93
+ this.logging = true
94
+ const name = this.form.getFieldValue('name')
95
+ const password = this.form.getFieldValue('password')
96
+ login(name, password).then(this.afterLogin)
97
+ }
98
+ })
99
+ },
100
+ afterLogin (res) {
101
+ const name = this.form.getFieldValue('name')
102
+ const password = this.form.getFieldValue('password')
103
+ this.logging = false
104
+ const loginRes = res.states
105
+ if (loginRes === '登录成功') {
106
+ const encrypt = new JSEncrypt()
107
+ encrypt.setPublicKey('MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqPvovSfXcwBbW8cKMCgwqNpsYuzF8RPAPFb7LGsnVo44JhM/xxzDyzoYtdfNmtbIuKVi9PzIsyp6rg+09gbuI6UGwBZ5DWBDBMqv5MPdOF5dCQkB2Bbr5yPfURPENypUz+pBFBg41d+BC+rwRiXELwKy7Y9caD/MtJyHydj8OUwIDAQAB')
108
+ const data = encrypt.encrypt(JSON.stringify({ username: name, password: password }))
109
+ localStorage.setItem(ACCESS_TOKEN, data)
110
+ // 获取路由配置
111
+ getRoutesConfig(data).then(result => {
112
+ Vue.$login.login(result).then(() => {
113
+ const user = Object.assign({
114
+ username: result.ename,
115
+ name: result.name,
116
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/jZUIxmJycoymBprLOUbT.png',
117
+ address: '西安市',
118
+ position: positions[0]
119
+ }, result)
120
+ this.setUser(user)
121
+ this.setPermissions([{ id: 'queryForm', operation: ['add', 'edit'] }])
122
+ this.setRoles([{ id: 'admin', operation: ['add', 'edit', 'delete'] }])
123
+ let timestamp = new Date().getTime()// 当前的时间戳
124
+ timestamp = timestamp + 60 * 60 * 1000
125
+ // 格式化时间获取年月日, 登陆过期时间
126
+ const dateAfter = new Date(timestamp)
127
+ setAuthorization({ token: data, expireAt: dateAfter })
128
+ loadRoutes(funcToRouter(user.functions))
129
+ if (result.deps === '用户工单登记') {
130
+ this.$router.push(ticketPage).catch(() => {})
131
+ } else {
132
+ this.$router.push(homePage).catch(() => {})
133
+ }
134
+ this.$message.success(timeFix().CN + ',欢迎回来', 3)
135
+ })
136
+ })
137
+ } else {
138
+ this.error = loginRes
139
+ }
140
+ }
141
+ }
142
+ }
143
+ </script>
144
+
145
+ <style lang="less" scoped>
146
+ .common-layout{
147
+ .top {
148
+ text-align: center;
149
+ .header {
150
+ height: 44px;
151
+ line-height: 44px;
152
+ a {
153
+ text-decoration: none;
154
+ }
155
+ .logo {
156
+ height: 44px;
157
+ vertical-align: top;
158
+ margin-right: 16px;
159
+ }
160
+ .title {
161
+ font-size: 33px;
162
+ color: @title-color;
163
+ font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif;
164
+ font-weight: 600;
165
+ position: relative;
166
+ top: 2px;
167
+ }
168
+ }
169
+ .desc {
170
+ font-size: 14px;
171
+ color: @text-color-second;
172
+ margin-top: 12px;
173
+ margin-bottom: 40px;
174
+ }
175
+ }
176
+ .login{
177
+ width: 368px;
178
+ margin: 0 auto;
179
+ @media screen and (max-width: 576px) {
180
+ width: 95%;
181
+ }
182
+ @media screen and (max-width: 320px) {
183
+ .captcha-button{
184
+ font-size: 14px;
185
+ }
186
+ }
187
+ .icon {
188
+ font-size: 24px;
189
+ color: @text-color-second;
190
+ margin-left: 16px;
191
+ vertical-align: middle;
192
+ cursor: pointer;
193
+ transition: color 0.3s;
194
+
195
+ &:hover {
196
+ color: @primary-color;
197
+ }
198
+ }
199
+ }
200
+ }
201
+ </style>
@@ -1,59 +1,58 @@
1
- // 视图组件
2
- const view = {
3
- tabs: () => import('@vue2-client/layouts/tabs'),
4
- blank: () => import('@vue2-client/layouts/BlankView'),
5
- page: () => import('@vue2-client/layouts/PageView'),
6
- singlePage: () => import('@vue2-client/layouts/SinglePageView')
7
- }
8
- // 动态路由对象定义
9
- const routerResource = {}
10
- // --------------------------------------基本视图组件--------------------------------------
11
- // 空白视图
12
- routerResource.blank = view.blank
13
- // 单页面视图
14
- routerResource.singlePage = view.singlePage
15
- // --------------------------------------系统配置--------------------------------------
16
- routerResource.system = view.blank
17
- // 字典管理
18
- routerResource.dictionaryManage = () => import(/* webpackChunkName: "dictionary" */ '@vue2-client/pages/system/dictionary')
19
- // 查询配置管理
20
- routerResource.queryParamsManage = () => import(/* webpackChunkName: "queryParams" */ '@vue2-client/pages/system/queryParams')
21
- // 系统问题反馈工单
22
- routerResource.submitTicket = () => import(/* webpackChunkName: "submitTicket" */ '@vue2-client/pages/system/ticket')
23
- // --------------------------------------报表组件--------------------------------------
24
- routerResource.reportTable = () => import(/* webpackChunkName: "ReportTableHome" */ '@vue2-client/pages/report/ReportTableHome')
25
- // --------------------------------------资源管理--------------------------------------
26
- routerResource.resourceManageMain = () => import(/* webpackChunkName: "resourceManageMain" */ '@vue2-client/pages/resourceManage/resourceManageMain')
27
-
28
- // 基础路由组件注册
29
- const routerMap = {
30
- login: {
31
- authority: '*',
32
- path: '/login',
33
- component: () => import('@vue2-client/pages/login')
34
- },
35
- root: {
36
- path: '/',
37
- name: '首页',
38
- redirect: '/login',
39
- component: view.tabs
40
- },
41
- exp403: {
42
- authority: '*',
43
- name: 'exp403',
44
- path: '403',
45
- component: () => import('@vue2-client/pages/exception/403')
46
- },
47
- exp404: {
48
- name: 'exp404',
49
- path: '404',
50
- component: () => import('@vue2-client/pages/exception/404')
51
- },
52
- exp500: {
53
- name: 'exp500',
54
- path: '500',
55
- component: () => import('@vue2-client/pages/exception/500')
56
- }
57
- }
58
- Object.assign(routerMap, routerResource)
59
- export default routerMap
1
+ // 视图组件
2
+ const view = {
3
+ tabs: () => import('@vue2-client/layouts/tabs'),
4
+ blank: () => import('@vue2-client/layouts/BlankView'),
5
+ page: () => import('@vue2-client/layouts/PageView')
6
+ }
7
+ // 动态路由对象定义
8
+ const routerResource = {}
9
+ // --------------------------------------基本视图组件--------------------------------------
10
+ // 空白视图
11
+ routerResource.blank = view.blank
12
+ // 单页面视图
13
+ routerResource.singlePage = view.blank
14
+ // --------------------------------------系统配置--------------------------------------
15
+ routerResource.system = view.blank
16
+ // 字典管理
17
+ routerResource.dictionaryManage = () => import(/* webpackChunkName: "dictionary" */ '@vue2-client/pages/system/dictionary')
18
+ // 查询配置管理
19
+ routerResource.queryParamsManage = () => import(/* webpackChunkName: "queryParams" */ '@vue2-client/pages/system/queryParams')
20
+ // 系统问题反馈工单
21
+ routerResource.submitTicket = () => import(/* webpackChunkName: "submitTicket" */ '@vue2-client/pages/system/ticket')
22
+ // --------------------------------------报表组件--------------------------------------
23
+ routerResource.reportTable = () => import(/* webpackChunkName: "ReportTableHome" */ '@vue2-client/pages/report/ReportTableHome')
24
+ // --------------------------------------资源管理--------------------------------------
25
+ routerResource.resourceManageMain = () => import(/* webpackChunkName: "resourceManageMain" */ '@vue2-client/pages/resourceManage/resourceManageMain')
26
+
27
+ // 基础路由组件注册
28
+ const routerMap = {
29
+ login: {
30
+ authority: '*',
31
+ path: '/login',
32
+ component: () => import('@vue2-client/pages/login')
33
+ },
34
+ root: {
35
+ path: '/',
36
+ name: '首页',
37
+ redirect: '/login',
38
+ component: view.tabs
39
+ },
40
+ exp403: {
41
+ authority: '*',
42
+ name: 'exp403',
43
+ path: '403',
44
+ component: () => import('@vue2-client/pages/exception/403')
45
+ },
46
+ exp404: {
47
+ name: 'exp404',
48
+ path: '404',
49
+ component: () => import('@vue2-client/pages/exception/404')
50
+ },
51
+ exp500: {
52
+ name: 'exp500',
53
+ path: '500',
54
+ component: () => import('@vue2-client/pages/exception/500')
55
+ }
56
+ }
57
+ Object.assign(routerMap, routerResource)
58
+ export default routerMap
@@ -1,33 +1,47 @@
1
- .week-mode{
2
- overflow: hidden;
3
- filter: invert(80%);
4
- }
5
- .beauty-scroll{
6
- scrollbar-color: @primary-color @primary-2;
7
- scrollbar-width: thin;
8
- -ms-overflow-style:none;
9
- position: relative;
10
- &::-webkit-scrollbar{
11
- width: 3px;
12
- height: 1px;
13
- }
14
- &::-webkit-scrollbar-thumb {
15
- border-radius: 3px;
16
- background: @primary-color;
17
- }
18
- &::-webkit-scrollbar-track {
19
- -webkit-box-shadow: inset 0 0 1px rgba(0,0,0,0);
20
- border-radius: 3px;
21
- background: @primary-3;
22
- }
23
- }
24
- .split-right{
25
- &:not(:last-child) {
26
- border-right: 1px solid rgba(98, 98, 98, 0.2);
27
- }
28
- }
29
- .disabled{
30
- cursor: not-allowed;
31
- color: @disabled-color;
32
- pointer-events: none;
33
- }
1
+ .week-mode{
2
+ overflow: hidden;
3
+ filter: invert(80%);
4
+ }
5
+ .beauty-scroll{
6
+ scrollbar-color: @primary-color @primary-2;
7
+ scrollbar-width: thin;
8
+ -ms-overflow-style:none;
9
+ position: relative;
10
+ &::-webkit-scrollbar{
11
+ width: 3px;
12
+ height: 1px;
13
+ }
14
+ &::-webkit-scrollbar-thumb {
15
+ border-radius: 3px;
16
+ background: @primary-color;
17
+ }
18
+ &::-webkit-scrollbar-track {
19
+ -webkit-box-shadow: inset 0 0 1px rgba(0,0,0,0);
20
+ border-radius: 3px;
21
+ background: @primary-3;
22
+ }
23
+ }
24
+ .split-right{
25
+ &:not(:last-child) {
26
+ border-right: 1px solid rgba(98, 98, 98, 0.2);
27
+ }
28
+ }
29
+ .disabled{
30
+ cursor: not-allowed;
31
+ color: @disabled-color;
32
+ pointer-events: none;
33
+ }
34
+
35
+ ::-webkit-scrollbar{
36
+ width: 5px;
37
+ height: 5px;
38
+ }
39
+ ::-webkit-scrollbar-thumb {
40
+ border-radius: 3px;
41
+ background: @primary-3;
42
+ }
43
+ ::-webkit-scrollbar-track {
44
+ -webkit-box-shadow: inset 0 0 1px rgba(0,0,0,0);
45
+ border-radius: 3px;
46
+ background: @primary-1;
47
+ }
@@ -63,11 +63,8 @@ function parseRoutes (routesConfig, routerMap) {
63
63
  router = routerMap['singlePage']
64
64
  item.path = item.name
65
65
  }
66
- // 当没在动态路由对象中找到时, 给404页面
67
- if (!router) {
68
- router = routerMap['exp404']
69
- item.path = item.name
70
- }
66
+ // 当没在动态路由对象中找到时, 不添加到路由
67
+ if (!router) return
71
68
  routeCfg = item
72
69
  }
73
70
  if (!router) {
@@ -112,6 +109,8 @@ function parseRoutes (routesConfig, routerMap) {
112
109
  if (routeCfg.children && routeCfg.children.length > 0) {
113
110
  route.children = parseRoutes(routeCfg.children, routerMap)
114
111
  }
112
+ // 当没有子并且自己时blank(空界面)时, 不添加到路由
113
+ if (route.component.name === 'blank' && route.children && route.children.length <= 0) return
115
114
  routes.push(route)
116
115
  })
117
116
  return routes
package/vue.config.js CHANGED
@@ -35,8 +35,8 @@ const isProd = process.env.NODE_ENV === 'production'
35
35
  // }
36
36
 
37
37
  const server = 'http://121.36.106.17:8400'
38
- const local = 'http://localhost:8445/webmeter'
39
- // const local = 'http://123.60.214.109:8405/webmeter'
38
+ // const local = 'http://localhost:8445/webmeter'
39
+ const local = 'http://123.60.214.109:8405/webmeter'
40
40
 
41
41
  module.exports = {
42
42
  devServer: {
@@ -1,15 +0,0 @@
1
- // 自定义配置,参考 ./default/setting.config.js,需要自定义的属性在这里配置即可
2
- module.exports = {
3
- theme: {
4
- color: '#1890ff',
5
- mode: 'dark'
6
- },
7
- fixedHeader: true,
8
- fixedTabs: true,
9
- multiPage: true,
10
- asyncRoutes: true,
11
- animate: {
12
- name: 'lightSpeed',
13
- direction: 'left'
14
- }
15
- }