Commit 70fba7ecac80a1cd8ec08052e8265641f2b56204

Authored by vben
1 parent 8f4d51a7

perf: performance optimization

README.en-US.md
@@ -30,6 +30,7 @@ @@ -30,6 +30,7 @@
30 - [Code contribution](#code-contribution) 30 - [Code contribution](#code-contribution)
31 - [Finished features](#finished-features) 31 - [Finished features](#finished-features)
32 - [Developing features](#developing-features) 32 - [Developing features](#developing-features)
  33 +- [Browser support](#browser-support)
33 34
34 ## Introduction 35 ## Introduction
35 36
@@ -238,3 +239,13 @@ yarn clean:lib # Delete node_modules, supported window @@ -238,3 +239,13 @@ yarn clean:lib # Delete node_modules, supported window
238 - [ ] System performance optimization 239 - [ ] System performance optimization
239 240
240 If you have more components/functions/suggestions/bugs/, welcome to submit pr or issue. 241 If you have more components/functions/suggestions/bugs/, welcome to submit pr or issue.
  242 +
  243 +## Browser support
  244 +
  245 +It is recommended to use the `Chrome` browser for local development. Development in the Firefox browser is relatively slow.
  246 +
  247 +Support modern browsers, Not currently supported ie11,Follow-up consideration support ie11
  248 +
  249 +| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
  250 +| :-: | :-: | :-: | :-: |
  251 +| Not currently supported | last 2 versions | last 2 versions | last 2 versions |
README.md
@@ -30,6 +30,7 @@ @@ -30,6 +30,7 @@
30 - [代码贡献](#代码贡献) 30 - [代码贡献](#代码贡献)
31 - [已完成功能](#已完成功能) 31 - [已完成功能](#已完成功能)
32 - [正在开发的功能](#正在开发的功能) 32 - [正在开发的功能](#正在开发的功能)
  33 +- [浏览器支持](#浏览器支持)
33 - [加入我们](#加入我们) 34 - [加入我们](#加入我们)
34 35
35 ## 介绍 36 ## 介绍
@@ -241,6 +242,16 @@ yarn clean:lib # 删除node_modules,兼容window系统 @@ -241,6 +242,16 @@ yarn clean:lib # 删除node_modules,兼容window系统
241 242
242 更多组件/功能/建议/bug/欢迎提交 pr 或者 issue 243 更多组件/功能/建议/bug/欢迎提交 pr 或者 issue
243 244
  245 +## 浏览器支持
  246 +
  247 +本地开发推荐使用`Chrome`浏览器,在火狐浏览器进行开发相对卡顿。
  248 +
  249 +支持现代浏览器, IE 暂不支持,后续考虑支持 ie11
  250 +
  251 +| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
  252 +| :-: | :-: | :-: | :-: |
  253 +| not support | last 2 versions | last 2 versions | last 2 versions |
  254 +
244 ## 加入我们 255 ## 加入我们
245 256
246 `Vue-Vben-Aadmin` 是完全开源免费的项目,在帮助开发者更方便地进行中大型管理系统开发,同时也提供 QQ 交流群(项目刚起步,人数较少,有兴趣的可以加群一起讨论),使用问题欢迎在群内提问。 257 `Vue-Vben-Aadmin` 是完全开源免费的项目,在帮助开发者更方便地进行中大型管理系统开发,同时也提供 QQ 交流群(项目刚起步,人数较少,有兴趣的可以加群一起讨论),使用问题欢迎在群内提问。
src/App.vue
@@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
15 15
16 import { useConfigProvider, useInitAppConfigStore, useListenerNetWork } from './useApp'; 16 import { useConfigProvider, useInitAppConfigStore, useListenerNetWork } from './useApp';
17 import { useLockPage } from '/@/hooks/web/useLockPage'; 17 import { useLockPage } from '/@/hooks/web/useLockPage';
  18 + import { useSetting } from '/@/hooks/core/useSetting';
  19 +
18 moment.locale('zh-cn'); 20 moment.locale('zh-cn');
19 export default defineComponent({ 21 export default defineComponent({
20 name: 'App', 22 name: 'App',
@@ -23,8 +25,14 @@ @@ -23,8 +25,14 @@
23 useInitAppConfigStore(); 25 useInitAppConfigStore();
24 useListenerNetWork(); 26 useListenerNetWork();
25 createBreakpointListen(); 27 createBreakpointListen();
  28 + const { projectSetting } = useSetting();
26 const { transformCellText } = useConfigProvider(); 29 const { transformCellText } = useConfigProvider();
27 - const { on: lockOn } = useLockPage(); 30 +
  31 + let lockOn = {};
  32 + if (projectSetting.lockTime) {
  33 + const { on } = useLockPage();
  34 + lockOn = on;
  35 + }
28 return { 36 return {
29 transformCellText, 37 transformCellText,
30 zhCN, 38 zhCN,
src/components/Drawer/src/BasicDrawer.tsx
@@ -6,12 +6,12 @@ import { @@ -6,12 +6,12 @@ import {
6 watchEffect, 6 watchEffect,
7 watch, 7 watch,
8 unref, 8 unref,
9 - getCurrentInstance, 9 + // getCurrentInstance,
10 nextTick, 10 nextTick,
11 toRaw, 11 toRaw,
12 } from 'vue'; 12 } from 'vue';
13 import { BasicTitle } from '/@/components/Basic'; 13 import { BasicTitle } from '/@/components/Basic';
14 -import { ScrollContainer, ScrollContainerOptions } from '/@/components/Container/index'; 14 +// import { ScrollContainer, ScrollContainerOptions } from '/@/components/Container/index';
15 import { FullLoading } from '/@/components/Loading/index'; 15 import { FullLoading } from '/@/components/Loading/index';
16 16
17 import { getSlot } from '/@/utils/helper/tsxHelper'; 17 import { getSlot } from '/@/utils/helper/tsxHelper';
@@ -35,16 +35,16 @@ export default defineComponent({ @@ -35,16 +35,16 @@ export default defineComponent({
35 setup(props, { slots, emit, attrs }) { 35 setup(props, { slots, emit, attrs }) {
36 // const { currentRoute } = useRouter(); 36 // const { currentRoute } = useRouter();
37 const scrollRef = ref<any>(null); 37 const scrollRef = ref<any>(null);
38 - /**  
39 - * @description: 获取配置ScrollContainer  
40 - */  
41 - const getScrollOptions = computed(  
42 - (): ScrollContainerOptions => {  
43 - return {  
44 - ...(props.scrollOptions as any),  
45 - };  
46 - }  
47 - ); 38 + // /**
  39 + // * @description: 获取配置ScrollContainer
  40 + // */
  41 + // const getScrollOptions = computed(
  42 + // (): ScrollContainerOptions => {
  43 + // return {
  44 + // ...(props.scrollOptions as any),
  45 + // };
  46 + // }
  47 + // );
48 48
49 const visibleRef = ref(false); 49 const visibleRef = ref(false);
50 const propsRef = ref<Partial<DrawerProps> | null>(null); 50 const propsRef = ref<Partial<DrawerProps> | null>(null);
@@ -95,33 +95,27 @@ export default defineComponent({ @@ -95,33 +95,27 @@ export default defineComponent({
95 } 95 }
96 ); 96 );
97 97
98 - // watch(  
99 - // () => currentRoute.value.path,  
100 - // () => {  
101 - // if (unref(visibleRef)) {  
102 - // visibleRef.value = false;  
103 - // } 98 + // function scrollBottom() {
  99 + // const scroll = unref(scrollRef);
  100 + // if (scroll) {
  101 + // scroll.scrollBottom();
104 // } 102 // }
105 - // );  
106 - function scrollBottom() {  
107 - const scroll = unref(scrollRef);  
108 - if (scroll) {  
109 - scroll.scrollBottom();  
110 - }  
111 - }  
112 - function scrollTo(to: number) {  
113 - const scroll = unref(scrollRef);  
114 - if (scroll) {  
115 - scroll.scrollTo(to);  
116 - }  
117 - }  
118 - function getScrollWrap() {  
119 - const scroll = unref(scrollRef);  
120 - if (scroll) {  
121 - return scroll.getScrollWrap();  
122 - }  
123 - return null;  
124 - } 103 + // }
  104 +
  105 + // function scrollTo(to: number) {
  106 + // const scroll = unref(scrollRef);
  107 + // if (scroll) {
  108 + // scroll.scrollTo(to);
  109 + // }
  110 + // }
  111 +
  112 + // function getScrollWrap() {
  113 + // const scroll = unref(scrollRef);
  114 + // if (scroll) {
  115 + // return scroll.getScrollWrap();
  116 + // }
  117 + // return null;
  118 + // }
125 // 取消事件 119 // 取消事件
126 async function onClose(e: any) { 120 async function onClose(e: any) {
127 const { closeFunc } = unref(getProps); 121 const { closeFunc } = unref(getProps);
@@ -225,12 +219,12 @@ export default defineComponent({ @@ -225,12 +219,12 @@ export default defineComponent({
225 ); 219 );
226 } 220 }
227 221
228 - const currentInstance = getCurrentInstance() as any;  
229 - if (getCurrentInstance()) {  
230 - currentInstance.scrollBottom = scrollBottom;  
231 - currentInstance.scrollTo = scrollTo;  
232 - currentInstance.getScrollWrap = getScrollWrap;  
233 - } 222 + // const currentInstance = getCurrentInstance() as any;
  223 + // if (getCurrentInstance()) {
  224 + // currentInstance.scrollBottom = scrollBottom;
  225 + // currentInstance.scrollTo = scrollTo;
  226 + // currentInstance.getScrollWrap = getScrollWrap;
  227 + // }
234 const drawerInstance: DrawerInstance = { 228 const drawerInstance: DrawerInstance = {
235 setDrawerProps: setDrawerProps, 229 setDrawerProps: setDrawerProps,
236 }; 230 };
@@ -259,7 +253,7 @@ export default defineComponent({ @@ -259,7 +253,7 @@ export default defineComponent({
259 class={[!unref(getProps).loading ? 'hidden' : '']} 253 class={[!unref(getProps).loading ? 'hidden' : '']}
260 tip="加载中..." 254 tip="加载中..."
261 /> 255 />
262 - <ScrollContainer 256 + {/* <ScrollContainer
263 ref={scrollRef} 257 ref={scrollRef}
264 {...{ ...attrs, ...unref(getScrollOptions) }} 258 {...{ ...attrs, ...unref(getScrollOptions) }}
265 style={{ 259 style={{
@@ -267,7 +261,19 @@ export default defineComponent({ @@ -267,7 +261,19 @@ export default defineComponent({
267 }} 261 }}
268 > 262 >
269 {() => getSlot(slots, 'default')} 263 {() => getSlot(slots, 'default')}
270 - </ScrollContainer> 264 + </ScrollContainer> */}
  265 + <div
  266 + ref={scrollRef}
  267 + {...attrs}
  268 + style={{
  269 + height: `calc(100% - ${footerHeight}px)`,
  270 + overflow: 'auto',
  271 + padding: '16px',
  272 + paddingBottom: '30px',
  273 + }}
  274 + >
  275 + {getSlot(slots, 'default')}
  276 + </div>
271 {renderFooter()} 277 {renderFooter()}
272 </> 278 </>
273 ), 279 ),
src/components/Loading/FullLoading.vue
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
42 width: 100%; 42 width: 100%;
43 height: 100%; 43 height: 100%;
44 // background: rgba(255, 255, 255, 0.3); 44 // background: rgba(255, 255, 255, 0.3);
45 - background: rgba(241, 241, 246, 0.8); 45 + background: rgba(241, 241, 246, 0.7);
46 justify-content: center; 46 justify-content: center;
47 align-items: center; 47 align-items: center;
48 } 48 }
src/components/Menu/src/index.less
@@ -162,9 +162,9 @@ @@ -162,9 +162,9 @@
162 162
163 // 层级样式 163 // 层级样式
164 &.ant-menu-dark { 164 &.ant-menu-dark {
165 - .ant-menu-item {  
166 - transition: unset;  
167 - } 165 + // .ant-menu-item {
  166 + // transition: unset;
  167 + // }
168 168
169 .ant-menu-item.ant-menu-item-selected.basic-menu-menu-item__level1, 169 .ant-menu-item.ant-menu-item-selected.basic-menu-menu-item__level1,
170 .ant-menu-submenu-selected.basic-menu-menu-item__level1 { 170 .ant-menu-submenu-selected.basic-menu-menu-item__level1 {
@@ -206,9 +206,18 @@ @@ -206,9 +206,18 @@
206 } 206 }
207 207
208 .ant-menu-submenu-title { 208 .ant-menu-submenu-title {
209 - height: @app-menu-item-height;  
210 // margin: 0; 209 // margin: 0;
211 - line-height: @app-menu-item-height; 210 + // line-height: @app-menu-item-height;
  211 + display: flex;
  212 + height: @app-menu-item-height;
  213 + align-items: center;
  214 + }
  215 +
  216 + &.ant-menu-inline-collapsed {
  217 + .ant-menu-item-selected {
  218 + background: unset !important;
  219 + box-shadow: none;
  220 + }
212 } 221 }
213 } 222 }
214 223
src/design/transition/fade.less
@@ -8,21 +8,20 @@ @@ -8,21 +8,20 @@
8 opacity: 0; 8 opacity: 0;
9 } 9 }
10 10
11 -// side-fade  
12 -.slide-fade-enter-active,  
13 -.slide-fade-leave-active {  
14 - transition: opacity 0.3s, transform 0.35s; 11 +/* fade-transform */
  12 +.slide-fade-leave-active,
  13 +.slide-fade-enter-active {
  14 + transition: all 0.3s;
15 } 15 }
16 16
17 -.slide-enter-from,  
18 -.slide-fade-enter { 17 +.slide-fade-enter-from {
19 opacity: 0; 18 opacity: 0;
20 - transform: translateX(-30%); 19 + transform: translateX(-30px);
21 } 20 }
22 21
23 .slide-fade-leave-to { 22 .slide-fade-leave-to {
24 opacity: 0; 23 opacity: 0;
25 - transform: translateX(30%); 24 + transform: translateX(30px);
26 } 25 }
27 26
28 // /////////////////////////////////////////////// 27 // ///////////////////////////////////////////////
src/design/transition/zoom.less
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 // zoom-fade 13 // zoom-fade
14 .zoom-fade-enter-active, 14 .zoom-fade-enter-active,
15 .zoom-fade-leave-active { 15 .zoom-fade-leave-active {
16 - transition: transform 0.1s, opacity 0.15s ease-out; 16 + transition: transform 0.15s, opacity 0.2s ease-out;
17 } 17 }
18 18
19 .zoom-fade-enter-from { 19 .zoom-fade-enter-from {
src/hooks/event/useEvent.ts
@@ -45,8 +45,6 @@ export function useEvent({ @@ -45,8 +45,6 @@ export function useEvent({
45 if (v) { 45 if (v) {
46 !unref(isAddRef) && addEventListener(v); 46 !unref(isAddRef) && addEventListener(v);
47 cleanUp(() => { 47 cleanUp(() => {
48 - // @ts-ignore  
49 - window.a = v;  
50 autoRemove && removeEventListener(v); 48 autoRemove && removeEventListener(v);
51 }); 49 });
52 } 50 }
src/hooks/event/useWindowSize.ts
@@ -21,6 +21,7 @@ export function useWindowSizeFn&lt;T&gt;(fn: Fn&lt;T&gt;, wait = 150, options?: WindowSizeOp @@ -21,6 +21,7 @@ export function useWindowSizeFn&lt;T&gt;(fn: Fn&lt;T&gt;, wait = 150, options?: WindowSizeOp
21 tryOnMounted(() => { 21 tryOnMounted(() => {
22 window.addEventListener('resize', handler); 22 window.addEventListener('resize', handler);
23 }); 23 });
  24 +
24 tryOnUnmounted(() => { 25 tryOnUnmounted(() => {
25 window.removeEventListener('resize', handler); 26 window.removeEventListener('resize', handler);
26 cancel(); 27 cancel();
src/hooks/web/useECharts.ts
@@ -14,6 +14,7 @@ export function useECharts( @@ -14,6 +14,7 @@ export function useECharts(
14 ) { 14 ) {
15 const chartInstanceRef = ref<Nullable<ECharts>>(null); 15 const chartInstanceRef = ref<Nullable<ECharts>>(null);
16 let resizeFn: Fn = resize; 16 let resizeFn: Fn = resize;
  17 + let removeResizeFn: Fn = () => {};
17 18
18 const [debounceResize] = useDebounce(resize, 200); 19 const [debounceResize] = useDebounce(resize, 200);
19 resizeFn = debounceResize; 20 resizeFn = debounceResize;
@@ -25,11 +26,12 @@ export function useECharts( @@ -25,11 +26,12 @@ export function useECharts(
25 return; 26 return;
26 } 27 }
27 chartInstanceRef.value = echarts.init(el, theme); 28 chartInstanceRef.value = echarts.init(el, theme);
28 - useEvent({ 29 + const { removeEvent } = useEvent({
29 el: window, 30 el: window,
30 name: 'resize', 31 name: 'resize',
31 listener: resizeFn, 32 listener: resizeFn,
32 }); 33 });
  34 + removeResizeFn = removeEvent;
33 const { widthRef, screenEnum } = useBreakpoint(); 35 const { widthRef, screenEnum } = useBreakpoint();
34 if (unref(widthRef) <= screenEnum.MD) { 36 if (unref(widthRef) <= screenEnum.MD) {
35 useTimeout(() => { 37 useTimeout(() => {
@@ -37,6 +39,9 @@ export function useECharts( @@ -37,6 +39,9 @@ export function useECharts(
37 }, 30); 39 }, 30);
38 } 40 }
39 } 41 }
  42 + tryOnUnmounted(() => {
  43 + removeResizeFn();
  44 + });
40 45
41 function setOptions(options: any, clear = true) { 46 function setOptions(options: any, clear = true) {
42 nextTick(() => { 47 nextTick(() => {
src/hooks/web/useFullScreen.ts
@@ -15,11 +15,7 @@ type FSEPropName = @@ -15,11 +15,7 @@ type FSEPropName =
15 | 'msFullscreenElement' 15 | 'msFullscreenElement'
16 | 'mozFullScreenElement' 16 | 'mozFullScreenElement'
17 | 'fullscreenElement'; 17 | 'fullscreenElement';
18 -type ONFSCPropName =  
19 - | 'onfullscreenchange'  
20 - | 'onwebkitfullscreenchange'  
21 - | 'onmozfullscreenchange'  
22 - | 'MSFullscreenChange'; 18 +type ONFSCPropName = 'onfullscreenchange' | 'onwebkitfullscreenchange' | 'MSFullscreenChange';
23 19
24 export function useFullscreen( 20 export function useFullscreen(
25 target: Ref<Nullable<HTMLElement>> = ref(document.documentElement), 21 target: Ref<Nullable<HTMLElement>> = ref(document.documentElement),
src/hooks/web/useLockPage.ts
@@ -3,6 +3,7 @@ import { useThrottle } from &#39;/@/hooks/core/useThrottle&#39;; @@ -3,6 +3,7 @@ import { useThrottle } from &#39;/@/hooks/core/useThrottle&#39;;
3 3
4 import { appStore } from '/@/store/modules/app'; 4 import { appStore } from '/@/store/modules/app';
5 import { userStore } from '/@/store/modules/user'; 5 import { userStore } from '/@/store/modules/user';
  6 +
6 export function useLockPage() { 7 export function useLockPage() {
7 let timeId: ReturnType<typeof setTimeout>; 8 let timeId: ReturnType<typeof setTimeout>;
8 9
src/layouts/default/multitabs/index.less
@@ -34,6 +34,12 @@ @@ -34,6 +34,12 @@
34 color: inherit; 34 color: inherit;
35 } 35 }
36 36
  37 + > div {
  38 + display: flex;
  39 + justify-content: center;
  40 + align-items: center;
  41 + }
  42 +
37 svg { 43 svg {
38 fill: @text-color-base; 44 fill: @text-color-base;
39 } 45 }
src/main.ts
1 import { createApp } from 'vue'; 1 import { createApp } from 'vue';
2 -import { setupAntd } from '/@/setup/ant-design-vue'; 2 +
3 import router, { setupRouter } from '/@/router'; 3 import router, { setupRouter } from '/@/router';
4 import { setupStore } from '/@/store'; 4 import { setupStore } from '/@/store';
5 -import App from './App.vue';  
6 -import { registerGlobComp } from '/@/components/registerGlobComp'; 5 +import { setupAntd } from '/@/setup/ant-design-vue';
7 import { setupDirectives } from '/@/setup/directives/index'; 6 import { setupDirectives } from '/@/setup/directives/index';
8 7
  8 +import { registerGlobComp } from '/@/components/registerGlobComp';
9 import { isDevMode, isProdMode, isUseMock } from '/@/utils/env'; 9 import { isDevMode, isProdMode, isUseMock } from '/@/utils/env';
10 -  
11 import { setupProdMockServer } from '../mock/_createProductionServer'; 10 import { setupProdMockServer } from '../mock/_createProductionServer';
  11 +
  12 +import App from './App.vue';
12 import '/@/design/index.less'; 13 import '/@/design/index.less';
13 14
14 const app = createApp(App); 15 const app = createApp(App);