fix(table): 修复表格搜索表单第一次加载闪动问题

This commit is contained in:
vben 2020-08-24 23:00:39 +08:00
parent a1ad81c3ff
commit 1e91ac64b7
13 changed files with 164 additions and 115 deletions

View File

@ -16,114 +16,112 @@ const resolve = require('../../build/getCwdPath');
function configOptimization(config) {
// 只为方便注释 true 这样写没意义
config.when(true || isProductionFn(), (config) => {
// createScriptExtPlugin(config);
// config.when(true || isProductionFn(), (config) => {
// createScriptExtPlugin(config);
config.optimization.runtimeChunk({
name: (entry) => `_r-${entry.name}`,
});
// config.optimization.runtimeChunk('single');
config.optimization.splitChunks({
chunks: 'all',
maxAsyncRequests: 6, //分割后按需加载的代码块最多允许的并行请求数在webpack5里默认值变为6
maxInitialRequests: 5, //分割后入口代码块最多允许的并行请求数在webpack5里默认值变为4
// maxInitialRequests: Infinity,
automaticNameMaxLength: 15, // 分割chunk自动命名最大长度
automaticNameDelimiter: '.', // 分割chunk自动命名分隔符
minSize: 30000, // 大小超过30kb的模块才会被提取
maxSize: 0, // 只是提示可以被违反会尽量将chunk分的比maxSize小当设为0代表能分则分分不了不会强制
minChunks: 1, //某个模块至少被多少代码块引用才会被提取成新的chunk
name: true, //每个缓存组打包得到的代码块的名称
cacheGroups: {
default: false,
// light: {
// name: 'theme-light',
// test: (m, c) => {
// return (
// m.constructor.name === 'CssModule' &&
// new RegExp('-light.less|theme=light').test(m._identifier)
// );
// },
// chunks: 'all',
// enforce: true,
// priority: 40,
// },
// dark: {
// name: 'theme-dark',
// test: (m, c) => {
// return (
// m.constructor.name === 'CssModule' &&
// new RegExp('-dark.less|theme=dark').test(m._identifier)
// );
// },
// chunks: 'all',
// enforce: true,
// priority: 40,
// },
// styles: {
// name: 'styles',
// test: /\.(css|scss|sass|less|styl)$/,
// chunks: 'async',
// enforce: true,
// priority: 30,
// },
commons: {
name: 'commons.chunk',
test: resolve('src/components'),
minChunks: 2,
priority: 20,
reuseExistingChunk: true,
},
vendor: {
priority: 10,
reuseExistingChunk: true,
test: /[\\/]node_modules[\\/]/,
name(module) {
const match = module.context.match(
/[\\/]node_modules[\\/](.*?)([\\/]|$)(.*?)([\\/]|$)/
);
let packageName = match[1];
// if (match[1] === '@xxx') {
// packageName += `-${match[3]}`;
// }
if (
packageName.indexOf('axios') !== -1 ||
packageName.indexOf('babel') !== -1 ||
packageName.indexOf('crypto-js') !== -1 ||
packageName.indexOf('moment') !== -1 ||
packageName.indexOf('lodash') !== -1 ||
packageName.indexOf('mutationobserver') !== -1 ||
packageName.indexOf('resize-observer-polyfill') !== -1 ||
packageName.indexOf('vue') !== -1 ||
packageName.indexOf('dom-align') !== -1 ||
packageName.indexOf('async-validator') !== -1 ||
packageName.indexOf('readable-stream') !== -1 ||
packageName.indexOf('browserify-sign') !== -1 ||
packageName.indexOf('regenerator-runtime') !== -1 ||
packageName.indexOf('core-js') !== -1
) {
packageName = 'entry-lib';
} else if (packageName.indexOf('ant-design') !== -1) {
packageName = 'design';
} else if (
packageName.indexOf('echarts') !== -1 ||
packageName.indexOf('zrender') !== -1 ||
packageName.indexOf('vue-baidu-map') !== -1
) {
packageName = 'chart';
} else if (packageName.indexOf('xlsx') !== -1) {
packageName = 'xlsx';
}
// else {
// packageName = 'vendor';
// }
// const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
return `${packageName.replace('@', '')}.chunk`;
},
config.optimization.runtimeChunk({
name: (entry) => `_r-${entry.name}`,
});
// config.optimization.runtimeChunk('single');
config.optimization.splitChunks({
chunks: 'all',
maxAsyncRequests: 6, //分割后按需加载的代码块最多允许的并行请求数在webpack5里默认值变为6
maxInitialRequests: 5, //分割后入口代码块最多允许的并行请求数在webpack5里默认值变为4
// maxInitialRequests: Infinity,
automaticNameMaxLength: 15, // 分割chunk自动命名最大长度
automaticNameDelimiter: '.', // 分割chunk自动命名分隔符
minSize: 30000, // 大小超过30kb的模块才会被提取
maxSize: 0, // 只是提示可以被违反会尽量将chunk分的比maxSize小当设为0代表能分则分分不了不会强制
minChunks: 1, //某个模块至少被多少代码块引用才会被提取成新的chunk
name: true, //每个缓存组打包得到的代码块的名称
cacheGroups: {
default: false,
// light: {
// name: 'theme-light',
// test: (m, c) => {
// return (
// m.constructor.name === 'CssModule' &&
// new RegExp('-light.less|theme=light').test(m._identifier)
// );
// },
// chunks: 'all',
// enforce: true,
// priority: 40,
// },
// dark: {
// name: 'theme-dark',
// test: (m, c) => {
// return (
// m.constructor.name === 'CssModule' &&
// new RegExp('-dark.less|theme=dark').test(m._identifier)
// );
// },
// chunks: 'all',
// enforce: true,
// priority: 40,
// },
// styles: {
// name: 'styles',
// test: /\.(css|scss|sass|less|styl)$/,
// chunks: 'async',
// enforce: true,
// priority: 30,
// },
commons: {
name: 'commons.chunk',
test: resolve('src/components'),
minChunks: 2,
priority: 20,
reuseExistingChunk: true,
},
vendor: {
priority: 10,
reuseExistingChunk: true,
test: /[\\/]node_modules[\\/]/,
name(module) {
const match = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)(.*?)([\\/]|$)/);
let packageName = match[1];
// if (match[1] === '@xxx') {
// packageName += `-${match[3]}`;
// }
if (
packageName.indexOf('axios') !== -1 ||
packageName.indexOf('babel') !== -1 ||
packageName.indexOf('crypto-js') !== -1 ||
packageName.indexOf('moment') !== -1 ||
packageName.indexOf('lodash') !== -1 ||
packageName.indexOf('mutationobserver') !== -1 ||
packageName.indexOf('resize-observer-polyfill') !== -1 ||
packageName.indexOf('vue') !== -1 ||
packageName.indexOf('dom-align') !== -1 ||
packageName.indexOf('async-validator') !== -1 ||
packageName.indexOf('readable-stream') !== -1 ||
packageName.indexOf('browserify-sign') !== -1 ||
packageName.indexOf('regenerator-runtime') !== -1 ||
packageName.indexOf('core-js') !== -1
) {
packageName = 'entry-lib';
} else if (packageName.indexOf('ant-design') !== -1) {
packageName = 'design';
} else if (
packageName.indexOf('echarts') !== -1 ||
packageName.indexOf('zrender') !== -1 ||
packageName.indexOf('vue-baidu-map') !== -1
) {
packageName = 'chart';
} else if (packageName.indexOf('xlsx') !== -1) {
packageName = 'xlsx';
}
// else {
// packageName = 'vendor';
// }
// const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
return `${packageName.replace('@', '')}.chunk`;
},
},
});
},
});
// });
}
module.exports = {

View File

@ -1,6 +1,6 @@
{
"name": "vue-vben-admin",
"version": "1.3.0",
"version": "1.3.1",
"private": true,
"keywords": [
"vue",

View File

@ -1,6 +1,6 @@
<script lang="tsx">
import { Drawer, Row, Col } from 'ant-design-vue';
import { defineComponent, ref, computed, watch, unref } from 'compatible-vue';
import { defineComponent, ref, computed, watch, unref, getCurrentInstance } from 'compatible-vue';
// import { BaseTitle } from '@/components/base/index';
import { Icon } from '@/components/icon/index';
import { BaseTitle } from '@/components/base/index';
@ -19,6 +19,8 @@
props: basicProps,
setup(props: DrawerProps, { slots, emit, listeners, root, attrs }) {
const { prefixCls, prefixVar } = useDesign('drawer');
const scrollRef = ref<any>(null);
/**
* @description: 获取配置ScrollContainer
*/
@ -29,6 +31,25 @@
};
}
);
function scrollBottom() {
const scroll = unref(scrollRef);
if (scroll) {
scroll.scrollBottom();
}
}
function scrollTo(to: number) {
const scroll = unref(scrollRef);
if (scroll) {
scroll.scrollTo(to);
}
}
function getScrollWrap() {
const scroll = unref(scrollRef);
if (scroll) {
return scroll.getScrollWrap();
}
return null;
}
const visibleRef = ref(false);
const propsRef = ref<Partial<DrawerProps> | null>(null);
@ -200,6 +221,12 @@
);
}
const currentInstace = getCurrentInstance() as any;
if (getCurrentInstance()) {
currentInstace.scrollBottom = scrollBottom;
currentInstace.scrollTo = scrollTo;
currentInstace.getScrollWrap = getScrollWrap;
}
const drawerInstance: DrawerInstance = {
setDrawerProps,
};
@ -219,6 +246,7 @@
<FullLoading absolute v-show={props.loading} tip="加载中..." />
{renderHeader()}
<ScrollContainer
ref={scrollRef}
props={unref(getScrollOptions)}
on={listeners}
style={{
@ -293,6 +321,7 @@
line-height: @footer-height;
text-align: right;
background: #fff;
border-top: 1px solid @border-color-base;
}
}
</style>

View File

@ -80,3 +80,8 @@ export interface DrawerProps extends Drawer, DrawerFooterProps {
closeFunc?: () => Promise<void>;
triggerWindowResize?: boolean;
}
export interface DrawerActionType {
scrollBottom: () => void;
scrollTo: (to: number) => void;
getScrollWrap: () => Element | null;
}

View File

@ -42,7 +42,7 @@ export function useDrawer(): UseDrawerReturnType {
unref(drawerRef)!.setDrawerProps(props);
},
isFirstLoadRef: ref(false),
openDrawer: (props: Partial<DrawerProps>): void => {
openDrawer: (props: Partial<DrawerProps> | boolean): void => {
// if (unref(isFirstLoadRef)) {
// isFirstLoadRef.value = false;
// innerProps = props;

View File

@ -92,7 +92,7 @@
});
const { realWidthRef, screenEnum } = useBreakpoint();
const [throttleUpdateAdvanced] = useThrottle(updateAdvanced, 30);
const [throttleUpdateAdvanced] = useThrottle(updateAdvanced, 30, { immediate: true });
watch(
[() => unref(getSchema), () => unref(isAdvancedRef), () => unref(realWidthRef)],
() => {

View File

@ -20,8 +20,7 @@
} as PropOptions<'throttle' | 'debounce'>,
color: {
type: String,
default: '',
} as PropOptions<string>,
} as PropOptions<'error' | 'warning' | 'success'>,
//
throttleTime: {
type: Number,

View File

@ -194,7 +194,7 @@ export function useSideBar({
const names = getAllParentData(findMenu, flatMenus);
names.unshift({ ...findMenu, children: undefined });
setTimeout(() => {
const ret = names.reverse();
const ret = [...names].reverse();
menuStore.commitCurrMenuState(ret);
}, 16);

View File

@ -12,7 +12,7 @@
name: 'BasicParallax',
props: basicProps,
setup(props: BasicProps, { listeners, slots }) {
const { prefixCls } = useDesign('parallax');
const { prefixCls, prefixVar } = useDesign('parallax');
const imgRef = ref<HTMLImageElement | null>(null);
const wrapRef = ref<HTMLDivElement | null>(null);
@ -26,8 +26,8 @@
windowHeight: 0,
windowBottom: 0,
});
const el = document.querySelector('.vben-default-layout__main.fixed');
const getScrollWrapElRef = computed(() => {
const el = document.querySelector(`.${prefixVar}-default-layout__main.fixed`);
const { getContainer } = props;
if (!isObject(getContainer)) {
return el;

View File

@ -90,7 +90,7 @@
const renderTitle = () => {
const title = unref(getMergeProps).title;
return (
getSlot(slots, 'title') || (
getSlot(slots, 'tableTitle') || (
<TableTitle
helpMessage={unref(getMergeProps).titleHelpMessage}
title={title}

View File

@ -34,6 +34,7 @@ export function useColumns(
let pushIndexColumns = false;
columns.forEach((item) => {
const { key, dataIndex } = item;
item.align = item.align || 'center';
if (ellipsis) {
if (!key) {
item.key = dataIndex;

View File

@ -128,7 +128,7 @@ export const basicProps = {
} as PropOptions<string | ((record: any) => string)>,
bordered: {
type: Boolean,
default: false,
default: true,
} as PropOptions<boolean>,
pagination: {
type: [Object, Boolean],

View File

@ -21,3 +21,20 @@ declare type ImportComponentPromise = Promise<typeof import('*.vue')>;
// ref?: string;
// }
// }
// declare module '*.vue' {
// import { Component, ComponentPublicInstance } from 'vue';
// const _default: Component & {
// // eslint-disable-next-line
// new (): ComponentPublicInstance<any>;
// };
// export default _default;
// }
declare type Nullable<T> = T | null;
declare type CustomizedHTMLElement<T> = HTMLElement & T;
declare type Indexable<T> = {
[key: string]: T;
};