perf: perf component

This commit is contained in:
vben 2020-11-26 21:19:39 +08:00
parent 19011296ed
commit 73c8e0c158
80 changed files with 529 additions and 631 deletions

View File

@ -1,16 +1,23 @@
## Wip ## Wip
## (破坏性更新) Breaking changes
- ClickOutSide 组件引入方式由 `import ClickOutSide from '/@/components/ClickOutSide/index.vue'`变更为`import { ClickOutSide } from '/@/components/ClickOutSide'`
- Button 组件引入方式由 `import ClickOutSide from '/@/components/Button/index.vue'`变更为`import { Button } from '/@/components/Button'`
- StrengthMeter 组件引入方式由 `import StrengthMeter from '/@/components/StrengthMeter'`变更为`import { StrengthMeter } from '/@/components/StrengthMeter'`
- 除示例外加入全局国际化功能,支持中文与英文
### ✨ Refactor ### ✨ Refactor
- 重构整体 layout。更改代码实现方式。代码更精简 - 重构整体 layout。更改代码实现方式。代码更精简
- 配置项重构 - 配置项重构
- 移除 messageSetting 配置 - 移除 messageSetting 配置
- BasicTitle 组件 `showSpan`=> `span`
### ✨ Features ### ✨ Features
- 缓存可以配置是否加密,默认生产环境开启 Aes 加密 - 缓存可以配置是否加密,默认生产环境开启 Aes 加密
- 新增标签页拖拽排序 - 新增标签页拖拽排序
- 除示例外加入全局国际化功能,支持中文与英文
### 🎫 Chores ### 🎫 Chores

View File

@ -69,7 +69,7 @@
### 环境要求 ### 环境要求
- `Node.js`: - 版本最好大于 `12.0.0` - `Node.js`: - 版本最好大于 `12.0.0`
- `yarn` > `npm` > `cnpm`: - 包管理工具. - `yarn` : - 包管理工具.
### UI 框架 ### UI 框架

View File

@ -38,6 +38,7 @@
"vue": "^3.0.3", "vue": "^3.0.3",
"vue-i18n": "^9.0.0-beta.8", "vue-i18n": "^9.0.0-beta.8",
"vue-router": "^4.0.0-rc.5", "vue-router": "^4.0.0-rc.5",
"vue-types": "^3.0.1",
"vuex": "^4.0.0-rc.2", "vuex": "^4.0.0-rc.2",
"vuex-module-decorators": "^1.0.1", "vuex-module-decorators": "^1.0.1",
"xlsx": "^0.16.9", "xlsx": "^0.16.9",

View File

@ -1,8 +1,7 @@
import AppLocalePicker from './src/AppLocalePicker.vue'; import AppLocalePicker from './src/AppLocalePicker.vue';
import AppPageFooter from './src/AppPageFooter.vue';
import AppLogo from './src/AppLogo.vue'; import AppLogo from './src/AppLogo.vue';
import { withInstall } from '../util'; import { withInstall } from '../util';
export { AppLocalePicker, AppPageFooter, AppLogo }; export { AppLocalePicker, AppLogo };
export default withInstall(AppLocalePicker, AppPageFooter, AppLogo); export default withInstall(AppLocalePicker, AppLogo);

View File

@ -23,18 +23,16 @@
import { LocaleType } from '/@/locales/types'; import { LocaleType } from '/@/locales/types';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
name: 'AppLocalPicker', name: 'AppLocalPicker',
components: { GlobalOutlined, Dropdown }, components: { GlobalOutlined, Dropdown },
props: { props: {
showText: { // Whether to display text
type: Boolean, showText: propTypes.bool.def(true),
default: true, // Whether to refresh the interface when changing
}, reload: propTypes.bool,
reload: {
type: Boolean,
default: false,
},
}, },
setup(props) { setup(props) {
const { localeList } = useLocaleSetting(); const { localeList } = useLocaleSetting();

View File

@ -9,7 +9,6 @@
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import type { PropType } from 'vue';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { useGlobSetting } from '/@/hooks/setting'; import { useGlobSetting } from '/@/hooks/setting';
@ -18,23 +17,23 @@
import { PageEnum } from '/@/enums/pageEnum'; import { PageEnum } from '/@/enums/pageEnum';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
name: 'AppLogo', name: 'AppLogo',
props: { props: {
/** /**
* The theme of the current parent component * The theme of the current parent component
*/ */
theme: { theme: propTypes.oneOf(['light', 'dark']),
type: String as PropType<string>, // Whether to show title
}, showTitle: propTypes.bool.def(true),
showTitle: {
type: Boolean,
default: true,
},
}, },
setup() { setup() {
const { getCollapsedShowTitle } = useMenuSetting(); const { getCollapsedShowTitle } = useMenuSetting();
const globSetting = useGlobSetting(); const globSetting = useGlobSetting();
const go = useGo(); const go = useGo();
function handleGoHome(): void { function handleGoHome(): void {

View File

@ -1,3 +1,9 @@
export { default as BasicArrow } from './src/BasicArrow.vue'; import BasicArrow from './src/BasicArrow.vue';
export { default as BasicHelp } from './src/BasicHelp.vue'; import BasicHelp from './src/BasicHelp.vue';
export { default as BasicTitle } from './src/BasicTitle.vue'; import BasicTitle from './src/BasicTitle.vue';
import { withInstall } from '../util';
export { BasicArrow, BasicHelp, BasicTitle };
export default withInstall(BasicArrow, BasicHelp, BasicTitle);

View File

@ -8,27 +8,30 @@
</span> </span>
</template> </template>
<script lang="ts"> <script lang="ts">
import type { PropType } from 'vue';
import { defineComponent, computed } from 'vue'; import { defineComponent, computed } from 'vue';
import { RightOutlined } from '@ant-design/icons-vue'; import { RightOutlined } from '@ant-design/icons-vue';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
name: 'BasicArrow', name: 'BasicArrow',
components: { RightOutlined }, components: { RightOutlined },
props: { props: {
// Expand contract, expand by default // Expand contract, expand by default
expand: { expand: propTypes.bool,
type: Boolean as PropType<boolean>, top: propTypes.bool,
default: true, bottom: propTypes.bool,
},
}, },
setup(props) { setup(props) {
const getClass = computed(() => { const getClass = computed(() => {
const preCls = 'base-arrow'; const { expand, top, bottom } = props;
const cls = [preCls]; return [
props.expand && cls.push(`${preCls}__active`); 'base-arrow',
return cls; {
'base-arrow__active': expand,
top,
bottom,
},
];
}); });
return { return {
@ -39,26 +42,29 @@
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.base-arrow { .base-arrow {
transform: rotate(-90deg); display: inline-block;
transform: rotate(0deg);
transition: all 0.3s ease 0.1s; transition: all 0.3s ease 0.1s;
transform-origin: center center; transform-origin: center center;
&.right {
transform: rotate(0deg);
> span {
transition: all 0.3s ease 0.1s !important;
}
}
&__active { &__active {
transform: rotate(90deg); transform: rotate(90deg);
} }
&.right.base-arrow__active { &.top {
span { transform: rotate(-90deg);
}
&.bottom {
transform: rotate(90deg); transform: rotate(90deg);
} }
&.top.base-arrow__active {
transform: rotate(90deg);
}
&.bottom.base-arrow__active {
transform: rotate(-90deg);
} }
} }
</style> </style>

View File

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import type { PropType } from 'vue'; import type { CSSProperties, PropType } from 'vue';
import { defineComponent, computed, unref, h } from 'vue'; import { defineComponent, computed, unref, h } from 'vue';
import { Tooltip } from 'ant-design-vue'; import { Tooltip } from 'ant-design-vue';
@ -8,37 +8,24 @@
import { getPopupContainer } from '/@/utils'; import { getPopupContainer } from '/@/utils';
import { isString, isArray } from '/@/utils/is'; import { isString, isArray } from '/@/utils/is';
import { getSlot } from '/@/utils/helper/tsxHelper'; import { getSlot } from '/@/utils/helper/tsxHelper';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
name: 'BasicHelp', name: 'BasicHelp',
components: { Tooltip }, components: { Tooltip },
props: { props: {
// max-width // max-width
maxWidth: { maxWidth: propTypes.string.def('600px'),
type: String as PropType<string>,
default: '600px',
},
// Whether to display the serial number // Whether to display the serial number
showIndex: { showIndex: propTypes.bool,
type: Boolean as PropType<boolean>, // color
default: false, color: propTypes.string.def('#ffffff'),
}, fontSize: propTypes.string.def('14px'),
placement: propTypes.string.def('right'),
absolute: propTypes.bool,
// Text list // Text list
text: { text: {
type: [Array, String] as PropType<string[] | string>, type: [Array, String] as PropType<string[] | string>,
}, },
// color
color: {
type: String as PropType<string>,
default: '#ffffff',
},
fontSize: {
type: String as PropType<string>,
default: '14px',
},
absolute: {
type: Boolean as PropType<boolean>,
default: false,
},
// //
position: { position: {
type: [Object] as PropType<any>, type: [Object] as PropType<any>,
@ -48,24 +35,24 @@
bottom: 0, bottom: 0,
}), }),
}, },
placement: {
type: String as PropType<string>,
defualt: 'right',
},
}, },
setup(props, { slots }) { setup(props, { slots }) {
const getOverlayStyleRef = computed(() => { const getOverlayStyleRef = computed(
(): CSSProperties => {
return { return {
maxWidth: props.maxWidth, maxWidth: props.maxWidth,
}; };
}); }
);
const getWrapStyleRef = computed(() => { const getWrapStyleRef = computed(
(): CSSProperties => {
return { return {
color: props.color, color: props.color,
fontSize: props.fontSize, fontSize: props.fontSize,
}; };
}); }
);
const getMainStyleRef = computed(() => { const getMainStyleRef = computed(() => {
return props.absolute ? props.position : {}; return props.absolute ? props.position : {};
@ -73,14 +60,17 @@
const renderTitle = () => { const renderTitle = () => {
const list = props.text; const list = props.text;
if (isString(list)) { if (isString(list)) {
return h('p', list); return h('p', list);
} }
if (isArray(list)) { if (isArray(list)) {
return list.map((item, index) => { return list.map((item, index) => {
return h('p', { key: item }, [props.showIndex ? `${index + 1}. ` : '', item]); return h('p', { key: item }, [props.showIndex ? `${index + 1}. ` : '', item]);
}); });
} }
return null; return null;
}; };
@ -95,7 +85,7 @@
style: unref(getWrapStyleRef), style: unref(getWrapStyleRef),
}, },
[renderTitle()] [renderTitle()]
) as any, ),
overlayClassName: 'base-help__wrap', overlayClassName: 'base-help__wrap',
autoAdjustOverflow: true, autoAdjustOverflow: true,
overlayStyle: unref(getOverlayStyleRef), overlayStyle: unref(getOverlayStyleRef),

View File

@ -1,5 +1,5 @@
<template> <template>
<span class="base-title" :class="{ 'show-span': showSpan && $slots.default }"> <span class="base-title" :class="{ 'show-span': span && $slots.default }">
<slot /> <slot />
<BasicHelp class="base-title__help" v-if="helpMessage" :text="helpMessage" /> <BasicHelp class="base-title__help" v-if="helpMessage" :text="helpMessage" />
</span> </span>
@ -10,6 +10,7 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import BasicHelp from './BasicHelp.vue'; import BasicHelp from './BasicHelp.vue';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
name: 'BasicTitle', name: 'BasicTitle',
@ -19,13 +20,7 @@
type: [String, Array] as PropType<string | string[]>, type: [String, Array] as PropType<string | string[]>,
default: '', default: '',
}, },
showSpan: { span: propTypes.bool,
type: Boolean as PropType<boolean>,
default: false,
},
},
setup() {
return {};
}, },
}); });
</script> </script>

View File

@ -0,0 +1,7 @@
import Breadcrumb from './src/Breadcrumb.vue';
import BreadcrumbItem from './src/BreadcrumbItem.vue';
import { withInstall } from '../util';
export { Breadcrumb, BreadcrumbItem };
export default withInstall(Breadcrumb, BreadcrumbItem);

View File

@ -5,20 +5,14 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import type { PropType } from 'vue';
import { defineComponent, provide, ref } from 'vue'; import { defineComponent, provide, ref } from 'vue';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
name: 'Breadcrumb', name: 'Breadcrumb',
props: { props: {
separator: { separator: propTypes.string.def('/'),
type: String as PropType<string>, separatorClass: propTypes.string,
default: '/',
},
separatorClass: {
type: String as PropType<string>,
default: '',
},
}, },
setup(props) { setup(props) {
const breadcrumbRef = ref<Nullable<HTMLElement>>(null); const breadcrumbRef = ref<Nullable<HTMLElement>>(null);
@ -32,7 +26,7 @@
}); });
</script> </script>
<style lang="less"> <style lang="less">
@import (reference) '../../design/index.less'; @import (reference) '../../../design/index.less';
.breadcrumb { .breadcrumb {
.unselect(); .unselect();

View File

@ -13,21 +13,14 @@
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useEventListener } from '/@/hooks/event/useEventListener'; import { useEventListener } from '/@/hooks/event/useEventListener';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
name: 'BreadcrumbItem', name: 'BreadcrumbItem',
props: { props: {
to: { to: propTypes.oneOfType([propTypes.string, propTypes.object]),
type: [String, Object], replace: propTypes.bool,
default: '', isLink: propTypes.bool,
},
replace: {
type: Boolean,
default: false,
},
isLink: {
type: Boolean,
default: false,
},
}, },
setup(props) { setup(props) {
const linkRef = ref<Nullable<HTMLElement>>(null); const linkRef = ref<Nullable<HTMLElement>>(null);

View File

@ -0,0 +1,6 @@
import Button from './src/BasicButton.vue';
import { withInstall } from '../util';
export { Button };
export default withInstall(Button);

View File

@ -8,51 +8,33 @@
</Button> </Button>
</template> </template>
<script lang="ts"> <script lang="ts">
import { PropType } from 'vue';
import { defineComponent, computed } from 'vue'; import { defineComponent, computed } from 'vue';
import { Button } from 'ant-design-vue'; import { Button } from 'ant-design-vue';
import Icon from '/@/components/Icon'; import Icon from '/@/components/Icon';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
name: 'AButton', name: 'AButton',
inheritAttrs: false, inheritAttrs: false,
components: { Button, Icon }, components: { Button, Icon },
props: { props: {
type: { type: propTypes.oneOf(['primary', 'default', 'danger', 'dashed', 'link']).def('default'),
type: String as PropType<'primary' | 'default' | 'danger' | 'dashed' | 'link'>, color: propTypes.oneOf(['error', 'warning', 'success', '']),
default: 'default', loading: propTypes.bool,
}, disabled: propTypes.bool,
color: { preIcon: propTypes.string,
type: String as PropType<'error' | 'warning' | 'success' | ''>, postIcon: propTypes.string,
},
loading: {
type: Boolean as PropType<boolean>,
default: false,
},
disabled: {
type: Boolean as PropType<boolean>,
default: false,
},
preIcon: {
type: String as PropType<string>,
},
postIcon: {
type: String as PropType<string>,
},
}, },
setup(props, { attrs }) { setup(props, { attrs }) {
const getIsCircleBtn = computed(() => { const getIsCircleBtn = computed(() => attrs.shape === 'circle');
return attrs.shape === 'circle';
});
const getColor = computed(() => { const getColor = computed(() => {
const { color, disabled } = props; const { color, disabled } = props;
return [ return {
{
[`ant-btn-${color}`]: !!color, [`ant-btn-${color}`]: !!color,
[`is-disabled`]: disabled, [`is-disabled`]: disabled,
}, };
];
}); });
const getBindValue = computed((): any => { const getBindValue = computed((): any => {

View File

@ -1,66 +0,0 @@
import { VNodeChild } from 'vue';
export interface BasicButtonProps {
/**
* can be set to primary ghost dashed danger(added in 2.7) or omitted (meaning default)
* @default 'default'
* @type string
*/
type?: 'primary' | 'danger' | 'dashed' | 'ghost' | 'default';
/**
* set the original html type of button
* @default 'button'
* @type string
*/
htmlType?: 'button' | 'submit' | 'reset' | 'menu';
/**
* set the icon of button
* @type string
*/
icon?: VNodeChild | JSX.Element;
/**
* can be set to circle or circle-outline or omitted
* @type string
*/
shape?: 'circle' | 'circle-outline';
/**
* can be set to small large or omitted
* @default 'default'
* @type string
*/
size?: 'small' | 'large' | 'default';
/**
* set the loading status of button
* @default false
* @type boolean | { delay: number }
*/
loading?: boolean | { delay: number };
/**
* disabled state of button
* @default false
* @type boolean
*/
disabled?: boolean;
/**
* make background transparent and invert text and border colors, added in 2.7
* @default false
* @type boolean
*/
ghost?: boolean;
/**
* option to fit button width to its parent width
* @default false
* @type boolean
*/
block?: boolean;
onClick?: (e?: Event) => void;
}

View File

@ -0,0 +1,6 @@
import ClickOutSide from './src/index.vue';
import { withInstall } from '../util';
export { ClickOutSide };
export default withInstall(ClickOutSide);

View File

@ -9,9 +9,8 @@
export default defineComponent({ export default defineComponent({
name: 'ClickOutSide', name: 'ClickOutSide',
setup(_, { emit }) { setup(_, { emit }) {
const wrapRef = ref<Nullable<HTMLDivElement | null>>(null); const wrapRef = ref<ElRef>(null);
useClickOutside(wrapRef as Ref<HTMLDivElement>, () => { useClickOutside(wrapRef as Ref<HTMLDivElement>, () => {
emit('clickOutside'); emit('clickOutside');

View File

@ -1,5 +1,10 @@
export { default as ScrollContainer } from './src/ScrollContainer.vue'; import ScrollContainer from './src/ScrollContainer.vue';
export { default as CollapseContainer } from './src/collapse/CollapseContainer.vue'; import CollapseContainer from './src/collapse/CollapseContainer.vue';
export { default as LazyContainer } from './src/LazyContainer.vue'; import LazyContainer from './src/LazyContainer.vue';
import { withInstall } from '../util';
export * from './src/types.d'; export * from './src/types';
export { ScrollContainer, CollapseContainer, LazyContainer };
export default withInstall(ScrollContainer, CollapseContainer, LazyContainer);

View File

@ -24,19 +24,20 @@
import { Skeleton } from 'ant-design-vue'; import { Skeleton } from 'ant-design-vue';
import { useTimeoutFn } from '/@/hooks/core/useTimeout'; import { useTimeoutFn } from '/@/hooks/core/useTimeout';
import { useIntersectionObserver } from '/@/hooks/event/useIntersectionObserver'; import { useIntersectionObserver } from '/@/hooks/event/useIntersectionObserver';
import { propTypes } from '/@/utils/propTypes';
interface State { interface State {
isInit: boolean; isInit: boolean;
loading: boolean; loading: boolean;
intersectionObserverInstance: IntersectionObserver | null; intersectionObserverInstance: IntersectionObserver | null;
} }
export default defineComponent({ export default defineComponent({
name: 'LazyContainer', name: 'LazyContainer',
components: { Skeleton }, components: { Skeleton },
props: { props: {
// Waiting time, if the time is specified, whether visible or not, it will be automatically loaded after the specified time // Waiting time, if the time is specified, whether visible or not, it will be automatically loaded after the specified time
timeout: { timeout: propTypes.number,
type: Number as PropType<number>,
},
// The viewport where the component is located. If the component is scrolling in the page container, the viewport is the container // The viewport where the component is located. If the component is scrolling in the page container, the viewport is the container
viewport: { viewport: {
@ -47,33 +48,18 @@
}, },
// Preload threshold, css unit // Preload threshold, css unit
threshold: { threshold: propTypes.string.def('0px'),
type: String as PropType<string>,
default: '0px',
},
// The scroll direction of the viewport, vertical represents the vertical direction, horizontal represents the horizontal direction // The scroll direction of the viewport, vertical represents the vertical direction, horizontal represents the horizontal direction
direction: { direction: propTypes.oneOf(['vertical', 'horizontal']).def('vertical'),
type: String as PropType<'vertical' | 'horizontal'>,
default: 'vertical',
},
// The label name of the outer container that wraps the component // The label name of the outer container that wraps the component
tag: { tag: propTypes.string.def('div'),
type: String as PropType<string>,
default: 'div',
},
maxWaitingTime: { maxWaitingTime: propTypes.number.def(80),
type: Number as PropType<number>,
default: 80,
},
// transition name // transition name
transitionName: { transitionName: propTypes.string.def('lazy-container'),
type: String as PropType<string>,
default: 'lazy-container',
},
}, },
emits: ['init'], emits: ['init'],
setup(props, { emit }) { setup(props, { emit }) {

View File

@ -10,11 +10,9 @@
</template> </template>
<script lang="ts"> <script lang="ts">
// component
import { defineComponent, ref, unref, nextTick } from 'vue'; import { defineComponent, ref, unref, nextTick } from 'vue';
import { Scrollbar } from '/@/components/Scrollbar'; import { Scrollbar } from '/@/components/Scrollbar';
// hook
import { useScrollTo } from '/@/hooks/event/useScrollTo'; import { useScrollTo } from '/@/hooks/event/useScrollTo';
export default defineComponent({ export default defineComponent({
@ -26,6 +24,7 @@
function scrollTo(to: number, duration = 500) { function scrollTo(to: number, duration = 500) {
const scrollbar = unref(scrollbarRef); const scrollbar = unref(scrollbarRef);
if (!scrollbar) return; if (!scrollbar) return;
nextTick(() => { nextTick(() => {
const { start } = useScrollTo({ const { start } = useScrollTo({
el: unref(scrollbar.$.wrap), el: unref(scrollbar.$.wrap),
@ -45,6 +44,7 @@
function scrollBottom() { function scrollBottom() {
const scrollbar = unref(scrollbarRef); const scrollbar = unref(scrollbarRef);
if (!scrollbar) return; if (!scrollbar) return;
nextTick(() => { nextTick(() => {
const scrollHeight = scrollbar.$.wrap.scrollHeight as number; const scrollHeight = scrollbar.$.wrap.scrollHeight as number;
const { start } = useScrollTo({ const { start } = useScrollTo({
@ -54,6 +54,7 @@
start(); start();
}); });
} }
return { return {
scrollbarRef, scrollbarRef,
scrollTo, scrollTo,

View File

@ -5,6 +5,7 @@
<slot name="title" /> <slot name="title" />
</template> </template>
</CollapseHeader> </CollapseHeader>
<CollapseTransition :enable="canExpan"> <CollapseTransition :enable="canExpan">
<Skeleton v-if="loading" /> <Skeleton v-if="loading" />
<div class="collapse-container__body" v-else v-show="show"> <div class="collapse-container__body" v-else v-show="show">
@ -22,36 +23,31 @@
<script lang="ts"> <script lang="ts">
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import { defineComponent, ref, unref } from 'vue'; import { defineComponent, ref } from 'vue';
// component // component
import { Skeleton } from 'ant-design-vue';
import { CollapseTransition } from '/@/components/Transition/index'; import { CollapseTransition } from '/@/components/Transition/index';
import CollapseHeader from './CollapseHeader.vue'; import CollapseHeader from './CollapseHeader.vue';
import { Skeleton } from 'ant-design-vue';
import LazyContainer from '../LazyContainer.vue'; import LazyContainer from '../LazyContainer.vue';
import { triggerWindowResize } from '/@/utils/event/triggerWindowResizeEvent'; import { triggerWindowResize } from '/@/utils/event/triggerWindowResizeEvent';
// hook // hook
import { useTimeoutFn } from '/@/hooks/core/useTimeout'; import { useTimeoutFn } from '/@/hooks/core/useTimeout';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
name: 'CollapseContainer',
components: { components: {
Skeleton, Skeleton,
LazyContainer, LazyContainer,
CollapseHeader, CollapseHeader,
CollapseTransition, CollapseTransition,
}, },
name: 'CollapseContainer',
props: { props: {
title: { title: propTypes.string.def(''),
type: String as PropType<string>,
default: '',
},
// Can it be expanded // Can it be expanded
canExpan: { canExpan: propTypes.bool.def(true),
type: Boolean as PropType<boolean>,
default: true,
},
// Warm reminder on the right side of the title // Warm reminder on the right side of the title
helpMessage: { helpMessage: {
type: [Array, String] as PropType<string[] | string>, type: [Array, String] as PropType<string[] | string>,
@ -59,41 +55,27 @@
}, },
// Whether to trigger window.resize when expanding and contracting, // Whether to trigger window.resize when expanding and contracting,
// Can adapt to tables and forms, when the form shrinks, the form triggers resize to adapt to the height // Can adapt to tables and forms, when the form shrinks, the form triggers resize to adapt to the height
triggerWindowResize: { triggerWindowResize: propTypes.bool,
type: Boolean as PropType<boolean>, loading: propTypes.bool,
default: false,
},
loading: {
type: Boolean as PropType<boolean>,
default: false,
},
// Delayed loading // Delayed loading
lazy: { lazy: propTypes.bool,
type: Boolean as PropType<boolean>,
default: false,
},
// Delayed loading time // Delayed loading time
lazyTime: { lazyTime: propTypes.number.def(0),
type: Number as PropType<number>,
default: 0,
},
}, },
setup(props) { setup(props) {
const showRef = ref(true); const show = ref(true);
/** /**
* @description: Handling development events * @description: Handling development events
*/ */
function handleExpand() { function handleExpand() {
const hasShow = !unref(showRef); show.value = !show.value;
showRef.value = hasShow;
if (props.triggerWindowResize) { if (props.triggerWindowResize) {
// 200 milliseconds here is because the expansion has animation, // 200 milliseconds here is because the expansion has animation,
useTimeoutFn(triggerWindowResize, 200); useTimeoutFn(triggerWindowResize, 200);
} }
} }
return { return {
show: showRef, show,
handleExpand, handleExpand,
}; };
}, },

View File

@ -11,7 +11,7 @@
<div class="collapse-container__action"> <div class="collapse-container__action">
<slot name="action" /> <slot name="action" />
<BasicArrow v-if="$attrs.canExpan" :expand="$attrs.show" @click="$emit('expand')" /> <BasicArrow v-if="$attrs.canExpan" top :expand="$attrs.show" @click="$emit('expand')" />
</div> </div>
</div> </div>
</template> </template>

View File

@ -1,2 +1,3 @@
export { createContextMenu, destroyContextMenu } from './src/createContextMenu'; export { createContextMenu, destroyContextMenu } from './src/createContextMenu';
export * from './src/types'; export * from './src/types';

View File

@ -1,22 +1,14 @@
import type { PropType, CSSProperties } from 'vue'; import type { PropType } from 'vue';
import type { Axis, ContextMenuItem } from './types'; import type { Axis, ContextMenuItem } from './types';
import { propTypes } from '/@/utils/propTypes';
export const props = { export const props = {
width: { width: propTypes.number.def(156),
type: Number as PropType<number>,
default: 156,
},
customEvent: { customEvent: {
type: Object as PropType<Event>, type: Object as PropType<Event>,
default: null, default: null,
}, },
styles: { styles: propTypes.style,
type: Object as PropType<CSSProperties>, showIcon: propTypes.bool.def(true),
default: null,
},
showIcon: {
type: Boolean as PropType<boolean>,
default: true,
},
axis: { axis: {
// The position of the right mouse button click // The position of the right mouse button click
type: Object as PropType<Axis>, type: Object as PropType<Axis>,

View File

@ -29,7 +29,7 @@ export interface ContextMenuProps {
} }
export interface ItemContentProps { export interface ItemContentProps {
showIcon: boolean; showIcon: boolean | undefined;
item: ContextMenuItem; item: ContextMenuItem;
handler: Fn; handler: Fn;
} }

View File

@ -1,2 +1,8 @@
// Transform vue-count-to to support vue3 version // Transform vue-count-to to support vue3 version
export { default as CountTo } from './src/index.vue';
import CountTo from './src/index.vue';
import { withInstall } from '../util';
export { CountTo };
export default withInstall(CountTo);

View File

@ -1,25 +1,10 @@
import { PropType } from 'vue'; import { PropType } from 'vue';
import { propTypes } from '/@/utils/propTypes';
export const countToProps = { export const countToProps = {
startVal: { startVal: propTypes.number.def(0),
type: Number as PropType<number>, endVal: propTypes.number.def(2020),
required: false, duration: propTypes.number.def(1300),
default: 0, autoplay: propTypes.bool.def(true),
},
endVal: {
type: Number as PropType<number>,
required: false,
default: 2017,
},
duration: {
type: Number as PropType<number>,
required: false,
default: 3000,
},
autoplay: {
type: Boolean as PropType<boolean>,
required: false,
default: true,
},
decimals: { decimals: {
type: Number as PropType<number>, type: Number as PropType<number>,
required: false, required: false,
@ -28,31 +13,11 @@ export const countToProps = {
return value >= 0; return value >= 0;
}, },
}, },
decimal: { decimal: propTypes.string.def('.'),
type: String as PropType<string>, separator: propTypes.string.def(','),
required: false, prefix: propTypes.string.def(''),
default: '.', suffix: propTypes.string.def(''),
}, useEasing: propTypes.bool.def(true),
separator: {
type: String as PropType<string>,
required: false,
default: ',',
},
prefix: {
type: String as PropType<string>,
required: false,
default: '',
},
suffix: {
type: String as PropType<string>,
required: false,
default: '',
},
useEasing: {
type: Boolean as PropType<boolean>,
required: false,
default: true,
},
easingFn: { easingFn: {
type: Function as PropType<(t: number, b: number, c: number, d: number) => number>, type: Function as PropType<(t: number, b: number, c: number, d: number) => number>,
default(t: number, b: number, c: number, d: number) { default(t: number, b: number, c: number, d: number) {

View File

@ -1,7 +1,8 @@
import { defineComponent, computed, ref, unref } from 'vue'; import type { DescOptions, DescInstance, DescItem } from './types';
import { defineComponent, computed, ref, unref, CSSProperties } from 'vue';
import { Descriptions } from 'ant-design-vue'; import { Descriptions } from 'ant-design-vue';
import { CollapseContainer, CollapseContainerOptions } from '/@/components/Container/index'; import { CollapseContainer, CollapseContainerOptions } from '/@/components/Container/index';
import type { DescOptions, DescInstance, DescItem } from './types';
import descProps from './props'; import descProps from './props';
import { isFunction } from '/@/utils/is'; import { isFunction } from '/@/utils/is';
@ -11,6 +12,7 @@ import { deepMerge } from '/@/utils';
const prefixCls = 'description'; const prefixCls = 'description';
export default defineComponent({ export default defineComponent({
name: 'Description',
props: descProps, props: descProps,
emits: ['register'], emits: ['register'],
setup(props, { attrs, slots, emit }) { setup(props, { attrs, slots, emit }) {
@ -72,17 +74,13 @@ export default defineComponent({
if (!labelStyle && !labelMinWidth) { if (!labelStyle && !labelMinWidth) {
return label; return label;
} }
return (
<div const labelStyles: CSSProperties = {
style={{
...labelStyle, ...labelStyle,
minWidth: `${labelMinWidth}px`, minWidth: `${labelMinWidth}px `,
}} };
> return <div style={labelStyles}>{label}</div>;
{label}
</div>
);
} }
function renderItem() { function renderItem() {
@ -90,9 +88,11 @@ export default defineComponent({
return unref(schema).map((item) => { return unref(schema).map((item) => {
const { render, field, span, show, contentMinWidth } = item; const { render, field, span, show, contentMinWidth } = item;
const { data } = unref(getProps) as any; const { data } = unref(getProps) as any;
if (show && isFunction(show) && !show(data)) { if (show && isFunction(show) && !show(data)) {
return null; return null;
} }
const getContent = () => const getContent = () =>
isFunction(render) isFunction(render)
? render(data && data[field], data) ? render(data && data[field], data)
@ -130,12 +130,9 @@ export default defineComponent({
const renderContainer = () => { const renderContainer = () => {
const content = props.useCollapse ? renderDesc() : <div>{renderDesc()}</div>; const content = props.useCollapse ? renderDesc() : <div>{renderDesc()}</div>;
// Reduce the dom level // Reduce the dom level
const { title, canExpand, helpMessage } = unref(getCollapseOptions);
return props.useCollapse ? ( return props.useCollapse ? (
<CollapseContainer <CollapseContainer title={title} canExpan={canExpand} helpMessage={helpMessage}>
title={unref(getMergeProps).title}
canExpan={unref(getCollapseOptions).canExpand}
helpMessage={unref(getCollapseOptions).helpMessage}
>
{{ {{
default: () => content, default: () => content,
action: () => getSlot(slots, 'action'), action: () => getSlot(slots, 'action'),

View File

@ -1,23 +1,13 @@
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import type { CollapseContainerOptions } from '/@/components/Container';
import type { DescItem } from './types'; import type { DescItem } from './types';
import { propTypes } from '/@/utils/propTypes';
export default { export default {
useCollapse: { useCollapse: propTypes.bool.def(true),
type: Boolean as PropType<boolean>, title: propTypes.string.def(''),
default: true, size: propTypes.oneOf(['small', 'default', 'middle', undefined]).def('small'),
}, bordered: propTypes.bool.def(true),
title: {
type: String as PropType<string>,
default: '',
},
size: {
type: String as PropType<'small' | 'default' | 'middle' | undefined>,
default: 'small',
},
bordered: {
type: Boolean as PropType<boolean>,
default: true,
},
column: { column: {
type: [Number, Object] as PropType<number | any>, type: [Number, Object] as PropType<number | any>,
default: () => { default: () => {
@ -25,15 +15,12 @@ export default {
}, },
}, },
collapseOptions: { collapseOptions: {
type: Object as PropType<any>, type: Object as PropType<CollapseContainerOptions>,
default: null, default: null,
}, },
schema: { schema: {
type: Array as PropType<Array<DescItem>>, type: Array as PropType<Array<DescItem>>,
default: () => [], default: () => [],
}, },
data: { data: propTypes.object,
type: Object as PropType<any>,
default: null,
},
}; };

View File

@ -88,6 +88,7 @@ export interface DescInstance {
} }
export type Register = (descInstance: DescInstance) => void; export type Register = (descInstance: DescInstance) => void;
/** /**
* @description: * @description:
*/ */

View File

@ -7,13 +7,11 @@ export function useDescription(props?: Partial<DescOptions>): UseDescReturnType
if (!getCurrentInstance()) { if (!getCurrentInstance()) {
throw new Error('Please put useDescription function in the setup function!'); throw new Error('Please put useDescription function in the setup function!');
} }
const descRef = ref<DescInstance | null>(null); const descRef = ref<Nullable<DescInstance>>(null);
const loadedRef = ref(false); const loadedRef = ref(false);
function register(instance: DescInstance) { function register(instance: DescInstance) {
if (unref(loadedRef) && isProdMode()) { if (unref(loadedRef) && isProdMode()) return;
return;
}
descRef.value = instance; descRef.value = instance;
props && instance.setDescProps(props); props && instance.setDescProps(props);
loadedRef.value = true; loadedRef.value = true;
@ -24,5 +22,6 @@ export function useDescription(props?: Partial<DescOptions>): UseDescReturnType
unref(descRef)!.setDescProps(descProps); unref(descRef)!.setDescProps(descProps);
}, },
}; };
return [register, methods]; return [register, methods];
} }

View File

@ -1,2 +1,7 @@
export { default as Dropdown } from './src/Dropdown'; import Dropdown from './src/Dropdown';
import { withInstall } from '../util';
export * from './src/types'; export * from './src/types';
export { Dropdown };
export default withInstall(Dropdown);

View File

@ -2,7 +2,6 @@ import type { Trigger } from './types';
import { defineComponent, computed, unref } from 'vue'; import { defineComponent, computed, unref } from 'vue';
import { Dropdown, Menu } from 'ant-design-vue'; import { Dropdown, Menu } from 'ant-design-vue';
import Icon from '/@/components/Icon/index'; import Icon from '/@/components/Icon/index';
import { basicDropdownProps } from './props'; import { basicDropdownProps } from './props';

View File

@ -1,6 +1,12 @@
export { default as ImportExcel } from './src/ImportExcel.vue'; import ImportExcel from './src/ImportExcel.vue';
export { default as ExportExcelModel } from './src/ExportExcelModel.vue'; import ExportExcelModel from './src/ExportExcelModel.vue';
import { withInstall } from '../util';
export * from './src/types';
export { jsonToSheetXlsx, aoaToSheetXlsx } from './src/Export2Excel'; export { jsonToSheetXlsx, aoaToSheetXlsx } from './src/Export2Excel';
export * from './src/types'; export { ImportExcel, ExportExcelModel };
export default withInstall(ImportExcel, ExportExcelModel);

View File

@ -1,14 +1,14 @@
import xlsx from 'xlsx'; import xlsx from 'xlsx';
import type { WorkBook } from 'xlsx'; import type { WorkBook } from 'xlsx';
import type { JsonToSheet, AoAToSheet } from './types'; import type { JsonToSheet, AoAToSheet } from './types';
// import { isObject } from '@/src/utils/is';
const { utils, writeFile } = xlsx; const { utils, writeFile } = xlsx;
const DEF_FILE_NAME = 'excel-list.xlsx';
export function jsonToSheetXlsx<T = any>({ export function jsonToSheetXlsx<T = any>({
data, data,
header, header,
filename = 'excel-list.xlsx', filename = DEF_FILE_NAME,
json2sheetOpts = {}, json2sheetOpts = {},
write2excelOpts = { bookType: 'xlsx' }, write2excelOpts = { bookType: 'xlsx' },
}: JsonToSheet<T>) { }: JsonToSheet<T>) {
@ -34,7 +34,7 @@ export function jsonToSheetXlsx<T = any>({
export function aoaToSheetXlsx<T = any>({ export function aoaToSheetXlsx<T = any>({
data, data,
header, header,
filename = 'excel-list.xlsx', filename = DEF_FILE_NAME,
write2excelOpts = { bookType: 'xlsx' }, write2excelOpts = { bookType: 'xlsx' },
}: AoAToSheet<T>) { }: AoAToSheet<T>) {
const arrData = [...data]; const arrData = [...data];

View File

@ -72,7 +72,6 @@
async function handleOk() { async function handleOk() {
const res = (await validateFields()) as ExportModalResult; const res = (await validateFields()) as ExportModalResult;
const { filename, bookType } = res; const { filename, bookType } = res;
emit('success', { emit('success', {
filename: `${filename.split('.').shift()}.${bookType}`, filename: `${filename.split('.').shift()}.${bookType}`,
bookType, bookType,

View File

@ -2,7 +2,7 @@ import type { ColEx } from './types/index';
import { defineComponent, unref, computed, PropType } from 'vue'; import { defineComponent, unref, computed, PropType } from 'vue';
import { Form, Col } from 'ant-design-vue'; import { Form, Col } from 'ant-design-vue';
import Button from '/@/components/Button/index.vue'; import { Button } from '/@/components/Button';
import { BasicArrow } from '/@/components/Basic/index'; import { BasicArrow } from '/@/components/Basic/index';
import { getSlot } from '/@/utils/helper/tsxHelper'; import { getSlot } from '/@/utils/helper/tsxHelper';
@ -12,7 +12,6 @@ const { t } = useI18n('component.form');
export default defineComponent({ export default defineComponent({
name: 'BasicFormAction', name: 'BasicFormAction',
emits: ['toggle-advanced'],
props: { props: {
show: { show: {
type: Boolean, type: Boolean,
@ -55,6 +54,7 @@ export default defineComponent({
default: false, default: false,
}, },
}, },
emits: ['toggle-advanced'],
setup(props, { slots, emit }) { setup(props, { slots, emit }) {
const getResetBtnOptionsRef = computed(() => { const getResetBtnOptionsRef = computed(() => {
return { return {
@ -112,7 +112,7 @@ export default defineComponent({
{() => ( {() => (
<> <>
{isAdvanced ? t('putAway') : t('unfold')} {isAdvanced ? t('putAway') : t('unfold')}
<BasicArrow expand={!isAdvanced} /> <BasicArrow expand={!isAdvanced} top />
</> </>
)} )}
</Button> </Button>

View File

@ -1,9 +1,10 @@
import type { NamePath, RuleObject } from 'ant-design-vue/lib/form/interface'; import type { NamePath, RuleObject } from 'ant-design-vue/lib/form/interface';
import type { VNode } from 'vue'; import type { VNode } from 'vue';
import type { BasicButtonProps } from '/@/components/Button/types'; import type { ButtonProps as AntdButtonProps } from 'ant-design-vue/es/button/buttonTypes';
import type { FormItem } from './formItem'; import type { FormItem } from './formItem';
import type { ColEx, ComponentType } from './index'; import type { ColEx, ComponentType } from './index';
import { TableActionType } from '../../../Table/src/types/table'; import type { TableActionType } from '/@/components/Table/src/types/table';
export type FieldMapToTime = [string, [string, string], string?][]; export type FieldMapToTime = [string, [string, string], string?][];
@ -18,7 +19,7 @@ export interface RenderCallbackParams {
field: string; field: string;
} }
export interface ButtonProps extends BasicButtonProps { export interface ButtonProps extends AntdButtonProps {
text?: string; text?: string;
} }

View File

@ -1,32 +1,35 @@
import './index.less';
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import { defineComponent, ref, watch, onMounted, nextTick, unref, computed } from 'vue'; import {
defineComponent,
ref,
watch,
onMounted,
nextTick,
unref,
computed,
CSSProperties,
} from 'vue';
import Iconify from '@purge-icons/generated'; import Iconify from '@purge-icons/generated';
import { isString } from '/@/utils/is'; import { isString } from '/@/utils/is';
import './index.less'; import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
name: 'GIcon', name: 'GIcon',
props: { props: {
// icon name // icon name
icon: { icon: propTypes.string,
type: String as PropType<string>,
required: true,
},
// icon color // icon color
color: { color: propTypes.string,
type: String as PropType<string>,
},
// icon size // icon size
size: { size: {
type: [String, Number] as PropType<string | number>, type: [String, Number] as PropType<string | number>,
default: 16, default: 16,
}, },
prefix: { prefix: propTypes.string.def(''),
type: String as PropType<string>,
default: '',
},
}, },
setup(props, { attrs }) { setup(props, { attrs }) {
const elRef = ref<Nullable<HTMLElement>>(null); const elRef = ref<ElRef>(null);
const getIconRef = computed(() => { const getIconRef = computed(() => {
const { icon, prefix } = props; const { icon, prefix } = props;
@ -54,7 +57,8 @@ export default defineComponent({
} }
}; };
const wrapStyleRef = computed((): any => { const wrapStyleRef = computed(
(): CSSProperties => {
const { size, color } = props; const { size, color } = props;
let fs = size; let fs = size;
if (isString(size)) { if (isString(size)) {
@ -65,7 +69,8 @@ export default defineComponent({
color, color,
display: 'inline-flex', display: 'inline-flex',
}; };
}); }
);
watch(() => props.icon, update, { flush: 'post' }); watch(() => props.icon, update, { flush: 'post' });

View File

@ -1,3 +1,7 @@
export { default as MarkDown } from './src/index.vue'; import MarkDown from './src/index.vue';
import { withInstall } from '../util';
export * from './src/types'; export * from './src/types';
export { MarkDown };
export default withInstall(MarkDown);

View File

@ -2,39 +2,27 @@
<div class="markdown" ref="wrapRef" /> <div class="markdown" ref="wrapRef" />
</template> </template>
<script lang="ts"> <script lang="ts">
import { import { defineComponent, ref, onMounted, unref, onUnmounted, nextTick, watchEffect } from 'vue';
defineComponent,
ref,
onMounted,
unref,
PropType,
onUnmounted,
nextTick,
watchEffect,
} from 'vue';
import Vditor from 'vditor'; import Vditor from 'vditor';
import 'vditor/dist/index.css'; import 'vditor/dist/index.css';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
emits: ['update:value'], emits: ['update:value'],
props: { props: {
height: { height: propTypes.number.def(360),
type: Number as PropType<number>, value: propTypes.string.def(''),
default: 360,
},
value: {
type: String,
default: '',
},
}, },
setup(props, { attrs, emit }) { setup(props, { attrs, emit }) {
const wrapRef = ref<Nullable<HTMLDivElement>>(null); const wrapRef = ref<ElRef>(null);
const vditorRef = ref<Nullable<Vditor>>(null); const vditorRef = ref<Nullable<Vditor>>(null);
const initedRef = ref(false); const initedRef = ref(false);
function init() { function init() {
const wrapEl = unref(wrapRef); const wrapEl = unref(wrapRef);
if (!wrapEl) return; if (!wrapEl) return;
const data = { ...attrs, ...props }; const bindValue = { ...attrs, ...props };
vditorRef.value = new Vditor(wrapEl, { vditorRef.value = new Vditor(wrapEl, {
mode: 'sv', mode: 'sv',
preview: { preview: {
@ -43,7 +31,7 @@
input: (v) => { input: (v) => {
emit('update:value', v); emit('update:value', v);
}, },
...data, ...bindValue,
cache: { cache: {
enable: false, enable: false,
}, },

View File

@ -3,7 +3,7 @@ import type { ModalProps, ModalMethods } from './types';
import { defineComponent, computed, ref, watch, unref, watchEffect } from 'vue'; import { defineComponent, computed, ref, watch, unref, watchEffect } from 'vue';
import Modal from './Modal'; import Modal from './Modal';
import Button from '/@/components/Button/index.vue'; import { Button } from '/@/components/Button';
import ModalWrapper from './ModalWrapper'; import ModalWrapper from './ModalWrapper';
import { BasicTitle } from '/@/components/Basic'; import { BasicTitle } from '/@/components/Basic';
import { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined } from '@ant-design/icons-vue'; import { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined } from '@ant-design/icons-vue';

View File

@ -0,0 +1,6 @@
import PageFooter from './src/PageFooter.vue';
import { withInstall } from '../util';
export { PageFooter };
export default withInstall(PageFooter);

View File

@ -14,10 +14,9 @@
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
export default defineComponent({ export default defineComponent({
name: 'AppFooterToolbar', name: 'PageFooter',
setup() { setup() {
const { getCalcContentWidth } = useMenuSetting(); const { getCalcContentWidth } = useMenuSetting();
return { getCalcContentWidth }; return { getCalcContentWidth };
}, },
}); });

View File

@ -1,84 +1,6 @@
import { PropType } from 'vue'; import StrengthMeter from './src/index';
import { withInstall } from '../util';
import { defineComponent, computed, ref, watch, unref, watchEffect } from 'vue'; export { StrengthMeter };
import { Input } from 'ant-design-vue'; export default withInstall(StrengthMeter);
import zxcvbn from 'zxcvbn';
import { extendSlots } from '/@/utils/helper/tsxHelper';
import './index.less';
const prefixCls = 'strength-meter';
export default defineComponent({
name: 'StrengthMeter',
emits: ['score-change', 'change'],
props: {
value: {
type: String as PropType<string>,
default: undefined,
},
userInputs: {
type: Array as PropType<string[]>,
default: () => [],
},
showInput: {
type: Boolean as PropType<boolean>,
default: true,
},
disabled: {
type: Boolean as PropType<boolean>,
default: false,
},
},
setup(props, { emit, attrs, slots }) {
const innerValueRef = ref('');
const getPasswordStrength = computed(() => {
const { userInputs, disabled } = props;
if (disabled) return null;
const innerValue = unref(innerValueRef);
const score = innerValue
? zxcvbn(unref(innerValueRef), (userInputs as string[]) || null).score
: null;
emit('score-change', score);
return score;
});
function handleChange(e: ChangeEvent) {
innerValueRef.value = e.target.value;
}
watchEffect(() => {
innerValueRef.value = props.value || '';
});
watch(
() => unref(innerValueRef),
(val) => {
emit('change', val);
}
);
return () => {
const { showInput, disabled } = props;
return (
<div class={prefixCls}>
{showInput && (
<Input.Password
{...attrs}
allowClear={true}
value={unref(innerValueRef)}
onChange={handleChange}
disabled={disabled}
>
{extendSlots(slots)}
</Input.Password>
)}
<div class={`${prefixCls}-bar`}>
<div class={`${prefixCls}-bar__fill`} data-score={unref(getPasswordStrength)}></div>
</div>
</div>
);
};
},
});

View File

@ -1,4 +1,4 @@
@import (reference) '../../design/index.less'; @import (reference) '../../../design/index.less';
.strength-meter { .strength-meter {
position: relative; position: relative;

View File

@ -0,0 +1,77 @@
import './index.less';
import { PropType } from 'vue';
import { defineComponent, computed, ref, watch, unref, watchEffect } from 'vue';
import { Input } from 'ant-design-vue';
import zxcvbn from 'zxcvbn';
import { extendSlots } from '/@/utils/helper/tsxHelper';
import { propTypes } from '/@/utils/propTypes';
const prefixCls = 'strength-meter';
export default defineComponent({
name: 'StrengthMeter',
props: {
value: propTypes.string,
userInputs: {
type: Array as PropType<string[]>,
default: () => [],
},
showInput: propTypes.bool.def(true),
disabled: propTypes.bool,
},
emits: ['score-change', 'change'],
setup(props, { emit, attrs, slots }) {
const innerValueRef = ref('');
const getPasswordStrength = computed(() => {
const { userInputs, disabled } = props;
if (disabled) return null;
const innerValue = unref(innerValueRef);
const score = innerValue
? zxcvbn(unref(innerValueRef), (userInputs as string[]) || null).score
: null;
emit('score-change', score);
return score;
});
function handleChange(e: ChangeEvent) {
innerValueRef.value = e.target.value;
}
watchEffect(() => {
innerValueRef.value = props.value || '';
});
watch(
() => unref(innerValueRef),
(val) => {
emit('change', val);
}
);
return () => {
const { showInput, disabled } = props;
return (
<div class={prefixCls}>
{showInput && (
<Input.Password
{...attrs}
allowClear={true}
value={unref(innerValueRef)}
onChange={handleChange}
disabled={disabled}
>
{extendSlots(slots)}
</Input.Password>
)}
<div class={`${prefixCls}-bar`}>
<div class={`${prefixCls}-bar__fill`} data-score={unref(getPasswordStrength)}></div>
</div>
</div>
);
};
},
});

View File

@ -3,7 +3,7 @@ import { Dropdown, Menu, Popconfirm } from 'ant-design-vue';
import Icon from '/@/components/Icon/index'; import Icon from '/@/components/Icon/index';
import { DownOutlined } from '@ant-design/icons-vue'; import { DownOutlined } from '@ant-design/icons-vue';
import { ActionItem } from '/@/components/Table'; import { ActionItem } from '/@/components/Table';
import Button from '/@/components/Button/index.vue'; import { Button } from '/@/components/Button';
const prefixCls = 'basic-table-action'; const prefixCls = 'basic-table-action';
export default defineComponent({ export default defineComponent({
name: 'TableAction', name: 'TableAction',

View File

@ -1,5 +1,7 @@
import '../style/editable-cell.less';
import { defineComponent, PropType, ref, unref, nextTick, watchEffect } from 'vue'; import { defineComponent, PropType, ref, unref, nextTick, watchEffect } from 'vue';
import ClickOutSide from '/@/components/ClickOutSide/index.vue'; import { ClickOutSide } from '/@/components/ClickOutSide';
import { RenderEditableCellParams } from '../types/table'; import { RenderEditableCellParams } from '../types/table';
import { ComponentType } from '../types/componentType'; import { ComponentType } from '../types/componentType';
@ -8,8 +10,6 @@ import { componentMap } from '../componentMap';
import { isString, isBoolean } from '/@/utils/is'; import { isString, isBoolean } from '/@/utils/is';
import { FormOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons-vue'; import { FormOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons-vue';
import '../style/editable-cell.less';
const prefixCls = 'editable-cell'; const prefixCls = 'editable-cell';
const EditableCell = defineComponent({ const EditableCell = defineComponent({
name: 'EditableCell', name: 'EditableCell',

View File

@ -8,7 +8,6 @@ export default () => {
props.onExpand(props.record, e); props.onExpand(props.record, e);
}} }}
expand={props.expanded} expand={props.expanded}
class="right"
/> />
); );
}; };

View File

@ -1 +1,5 @@
export { default as Tinymce } from './src/Editor.vue'; import Tinymce from './src/Editor.vue';
import { withInstall } from '../util';
export { Tinymce };
export default withInstall(Tinymce);

View File

@ -8,7 +8,6 @@
import { import {
defineComponent, defineComponent,
computed, computed,
onMounted,
nextTick, nextTick,
ref, ref,
unref, unref,
@ -24,6 +23,7 @@
import { snowUuid } from '/@/utils/uuid'; import { snowUuid } from '/@/utils/uuid';
import { bindHandlers } from './helper'; import { bindHandlers } from './helper';
import lineHeight from './lineHeight'; import lineHeight from './lineHeight';
import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
const CDN_URL = 'https://cdn.bootcdn.net/ajax/libs/tinymce/5.5.1'; const CDN_URL = 'https://cdn.bootcdn.net/ajax/libs/tinymce/5.5.1';
@ -91,8 +91,7 @@
editor.setMode(attrs.disabled ? 'readonly' : 'design'); editor.setMode(attrs.disabled ? 'readonly' : 'design');
} }
); );
onMountedOrActivated(() => {
onMounted(() => {
nextTick(() => { nextTick(() => {
init(); init();
}); });

View File

@ -13,14 +13,6 @@ export function createSimpleTransition(name: string, origin = 'top center 0', mo
type: Boolean as PropType<boolean>, type: Boolean as PropType<boolean>,
default: false, default: false,
}, },
// hideOnLeave: {
// type: Boolean as PropType<boolean>,
// default: false,
// },
// leaveAbsolute: {
// type: Boolean as PropType<boolean>,
// default: false,
// },
mode: { mode: {
type: String as PropType<Mode>, type: String as PropType<Mode>,
default: mode, default: mode,

View File

@ -1,4 +1,9 @@
export { default as BasicDragVerify } from './src/DragVerify'; import BasicDragVerify from './src/DragVerify';
export { default as RotateDragVerify } from './src/ImgRotate'; import RotateDragVerify from './src/ImgRotate';
import { withInstall } from '../util';
export * from './src/types'; export * from './src/types';
export { RotateDragVerify, BasicDragVerify };
export default withInstall(RotateDragVerify, BasicDragVerify);

View File

@ -1 +1,6 @@
export { default as VirtualScroll } from './src/index'; import VirtualScroll from './src/index';
import { withInstall } from '../util';
export { VirtualScroll };
export default withInstall(VirtualScroll);

View File

@ -1,4 +1,14 @@
import { defineComponent, computed, ref, unref, reactive, onMounted, watch, nextTick } from 'vue'; import {
defineComponent,
computed,
ref,
unref,
reactive,
onMounted,
watch,
nextTick,
CSSProperties,
} from 'vue';
import { useEventListener } from '/@/hooks/event/useEventListener'; import { useEventListener } from '/@/hooks/event/useEventListener';
import { convertToUnit } from '/@/components/util'; import { convertToUnit } from '/@/components/util';
@ -34,13 +44,16 @@ export default defineComponent({
return Math.min((props.items || []).length, state.last + unref(getBenchRef)); return Math.min((props.items || []).length, state.last + unref(getBenchRef));
}); });
const getContainerStyleRef = computed(() => { const getContainerStyleRef = computed(
(): CSSProperties => {
return { return {
height: convertToUnit((props.items || []).length * unref(getItemHeightRef)), height: convertToUnit((props.items || []).length * unref(getItemHeightRef)),
}; };
}); }
);
const getWrapStyleRef = computed((): object => { const getWrapStyleRef = computed(
(): CSSProperties => {
const styles: Record<string, string> = {}; const styles: Record<string, string> = {};
const height = convertToUnit(props.height); const height = convertToUnit(props.height);
const minHeight = convertToUnit(props.minHeight); const minHeight = convertToUnit(props.minHeight);
@ -56,7 +69,8 @@ export default defineComponent({
if (maxWidth) styles.maxWidth = maxWidth; if (maxWidth) styles.maxWidth = maxWidth;
if (width) styles.width = width; if (width) styles.width = width;
return styles; return styles;
}); }
);
watch([() => props.itemHeight, () => props.height], () => { watch([() => props.itemHeight, () => props.height], () => {
onScroll(); onScroll();

View File

@ -1,5 +1,5 @@
import Icon from './Icon/index'; import Icon from './Icon/index';
import Button from './Button/index.vue'; import { Button } from './Button';
import { import {
// Need // Need
Button as AntButton, Button as AntButton,

View File

@ -6,6 +6,7 @@ export function withInstall(...components: Component[]) {
components.forEach((comp) => { components.forEach((comp) => {
comp.name && app.component(comp.name, comp); comp.name && app.component(comp.name, comp);
}); });
return app;
}; };
} }

View File

@ -1,6 +1,7 @@
import type { PropType, FunctionalComponent } from 'vue'; import type { FunctionalComponent } from 'vue';
import { defineComponent, unref } from 'vue'; import { defineComponent, unref } from 'vue';
import { import {
DoubleRightOutlined, DoubleRightOutlined,
DoubleLeftOutlined, DoubleLeftOutlined,
@ -9,6 +10,7 @@ import {
} from '@ant-design/icons-vue'; } from '@ant-design/icons-vue';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
import { propTypes } from '/@/utils/propTypes';
const SiderTrigger: FunctionalComponent = () => { const SiderTrigger: FunctionalComponent = () => {
const { getCollapsed } = useMenuSetting(); const { getCollapsed } = useMenuSetting();
@ -29,13 +31,8 @@ const HeaderTrigger: FunctionalComponent<{
export default defineComponent({ export default defineComponent({
name: 'LayoutTrigger', name: 'LayoutTrigger',
props: { props: {
sider: { sider: propTypes.bool.def(true),
type: Boolean as PropType<boolean>, theme: propTypes.oneOf(['light', 'dark']),
default: true,
},
theme: {
type: String as PropType<string>,
},
}, },
setup(props) { setup(props) {
return () => { return () => {

View File

@ -3,9 +3,9 @@ import type { RouteLocationMatched } from 'vue-router';
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import { defineComponent, TransitionGroup, unref, watch, ref } from 'vue'; import { defineComponent, TransitionGroup, unref, watch, ref } from 'vue';
import Breadcrumb from '/@/components/Breadcrumb/Breadcrumb.vue';
import Icon from '/@/components/Icon'; import Icon from '/@/components/Icon';
import BreadcrumbItem from '/@/components/Breadcrumb/BreadcrumbItem.vue';
import { Breadcrumb, BreadcrumbItem } from '/@/components/Breadcrumb';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';

View File

@ -38,6 +38,7 @@ import { PageEnum } from '/@/enums/pageEnum';
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum'; import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
import { AppLocalePicker } from '/@/components/Application'; import { AppLocalePicker } from '/@/components/Application';
import { useI18n } from '/@/hooks/web/useI18n'; import { useI18n } from '/@/hooks/web/useI18n';
import { propTypes } from '/@/utils/propTypes';
interface TooltipItemProps { interface TooltipItemProps {
title: string; title: string;
@ -57,10 +58,7 @@ const TooltipItem: FunctionalComponent<TooltipItemProps> = (props, { slots }) =>
export default defineComponent({ export default defineComponent({
name: 'LayoutHeader', name: 'LayoutHeader',
props: { props: {
fixed: { fixed: propTypes.bool,
type: Boolean,
default: false,
},
}, },
setup(props) { setup(props) {
let logoEl: Element | null | undefined; let logoEl: Element | null | undefined;

View File

@ -37,7 +37,7 @@
export default defineComponent({ export default defineComponent({
props: { props: {
list: { list: {
type: Array as PropType<Array<ListItem>>, type: Array as PropType<ListItem[]>,
default: () => [], default: () => [],
}, },
}, },

View File

@ -2,7 +2,7 @@ import './LockAction.less';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal/index'; import { BasicModal, useModalInner } from '/@/components/Modal/index';
import Button from '/@/components/Button/index.vue'; import { Button } from '/@/components/Button';
import { BasicForm, useForm } from '/@/components/Form/index'; import { BasicForm, useForm } from '/@/components/Form/index';
import headerImg from '/@/assets/images/header.jpg'; import headerImg from '/@/assets/images/header.jpg';

View File

@ -15,32 +15,25 @@ import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { useGo } from '/@/hooks/web/usePage'; import { useGo } from '/@/hooks/web/usePage';
import { useSplitMenu } from './useLayoutMenu'; import { useSplitMenu } from './useLayoutMenu';
import { openWindow } from '/@/utils'; import { openWindow } from '/@/utils';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({ export default defineComponent({
name: 'LayoutMenu', name: 'LayoutMenu',
props: { props: {
theme: { theme: propTypes.oneOf(['light', 'dark']),
type: String as PropType<string>,
default: '',
},
splitType: { splitType: {
type: Number as PropType<MenuSplitTyeEnum>, type: Number as PropType<MenuSplitTyeEnum>,
default: MenuSplitTyeEnum.NONE, default: MenuSplitTyeEnum.NONE,
}, },
parentMenuPath: {
type: String as PropType<string>, // Whether to show search box
default: '', showSearch: propTypes.bool.def(true),
},
showSearch: { isHorizontal: propTypes.bool,
type: Boolean as PropType<boolean>, // menu Mode
default: true,
},
isHorizontal: {
type: Boolean as PropType<boolean>,
default: false,
},
menuMode: { menuMode: {
type: [String] as PropType<MenuModeEnum | null>, type: [String] as PropType<Nullable<MenuModeEnum>>,
default: '', default: '',
}, },
}, },

View File

@ -5,7 +5,7 @@ import defaultSetting from '/@/settings/projectSetting';
import { defineComponent, computed, unref, FunctionalComponent } from 'vue'; import { defineComponent, computed, unref, FunctionalComponent } from 'vue';
import { BasicDrawer } from '/@/components/Drawer/index'; import { BasicDrawer } from '/@/components/Drawer/index';
import { Divider, Switch, Tooltip, InputNumber, Select } from 'ant-design-vue'; import { Divider, Switch, Tooltip, InputNumber, Select } from 'ant-design-vue';
import Button from '/@/components/Button/index.vue'; import { Button } from '/@/components/Button';
import { CopyOutlined, RedoOutlined, CheckOutlined } from '@ant-design/icons-vue'; import { CopyOutlined, RedoOutlined, CheckOutlined } from '@ant-design/icons-vue';
import { MenuTypeEnum } from '/@/enums/menuEnum'; import { MenuTypeEnum } from '/@/enums/menuEnum';

View File

@ -13,5 +13,4 @@ export const localeList: DropMenu[] = [
event: 'en', event: 'en',
}, },
]; ];
export default messages; export default messages;

View File

@ -1,4 +1,5 @@
import { createApp } from 'vue'; import { createApp } from 'vue';
import App from './App.vue';
import router, { setupRouter } from '/@/router'; import router, { setupRouter } from '/@/router';
import { setupStore } from '/@/store'; import { setupStore } from '/@/store';
@ -6,12 +7,9 @@ import { setupAntd } from '/@/setup/ant-design-vue';
import { setupErrorHandle } from '/@/setup/error-handle'; import { setupErrorHandle } from '/@/setup/error-handle';
import { setupGlobDirectives } from '/@/setup/directives'; import { setupGlobDirectives } from '/@/setup/directives';
import { setupI18n } from '/@/setup/i18n'; import { setupI18n } from '/@/setup/i18n';
import { setupProdMockServer } from '../mock/_createProductionServer'; import { setupProdMockServer } from '../mock/_createProductionServer';
import { setApp } from '/@/setup/App'; import { setApp } from '/@/setup/App';
import App from './App.vue';
import { isDevMode, isProdMode, isUseMock } from '/@/utils/env'; import { isDevMode, isProdMode, isUseMock } from '/@/utils/env';
import '/@/design/index.less'; import '/@/design/index.less';

View File

@ -10,7 +10,7 @@ const form: AppRouteModule = {
redirect: '/form/basic', redirect: '/form/basic',
meta: { meta: {
icon: 'ant-design:table-outlined', icon: 'ant-design:table-outlined',
title: 'rroutes.demo.form.form', title: 'routes.demo.form.form',
}, },
}, },
@ -20,7 +20,7 @@ const form: AppRouteModule = {
name: 'FormBasicDemo', name: 'FormBasicDemo',
component: () => import('/@/views/demo/form/index.vue'), component: () => import('/@/views/demo/form/index.vue'),
meta: { meta: {
title: 'rroutes.demo.form.basic', title: 'routes.demo.form.basic',
}, },
}, },
{ {
@ -28,7 +28,7 @@ const form: AppRouteModule = {
name: 'UseFormDemo', name: 'UseFormDemo',
component: () => import('/@/views/demo/form/UseForm.vue'), component: () => import('/@/views/demo/form/UseForm.vue'),
meta: { meta: {
title: 'rroutes.demo.form.useForm', title: 'routes.demo.form.useForm',
}, },
}, },
{ {
@ -36,7 +36,7 @@ const form: AppRouteModule = {
name: 'RefFormDemo', name: 'RefFormDemo',
component: () => import('/@/views/demo/form/RefForm.vue'), component: () => import('/@/views/demo/form/RefForm.vue'),
meta: { meta: {
title: 'rroutes.demo.form.refForm', title: 'routes.demo.form.refForm',
}, },
}, },
{ {
@ -44,7 +44,7 @@ const form: AppRouteModule = {
name: 'AdvancedFormDemo', name: 'AdvancedFormDemo',
component: () => import('/@/views/demo/form/AdvancedForm.vue'), component: () => import('/@/views/demo/form/AdvancedForm.vue'),
meta: { meta: {
title: 'rroutes.demo.form.advancedForm', title: 'routes.demo.form.advancedForm',
}, },
}, },
{ {
@ -52,7 +52,7 @@ const form: AppRouteModule = {
name: 'RuleFormDemo', name: 'RuleFormDemo',
component: () => import('/@/views/demo/form/RuleForm.vue'), component: () => import('/@/views/demo/form/RuleForm.vue'),
meta: { meta: {
title: 'rroutes.demo.form.ruleForm', title: 'routes.demo.form.ruleForm',
}, },
}, },
{ {
@ -60,7 +60,7 @@ const form: AppRouteModule = {
name: 'DynamicFormDemo', name: 'DynamicFormDemo',
component: () => import('/@/views/demo/form/DynamicForm.vue'), component: () => import('/@/views/demo/form/DynamicForm.vue'),
meta: { meta: {
title: 'rroutes.demo.form.dynamicForm', title: 'routes.demo.form.dynamicForm',
}, },
}, },
{ {
@ -68,7 +68,7 @@ const form: AppRouteModule = {
name: 'CustomerFormDemo', name: 'CustomerFormDemo',
component: () => import('/@/views/demo/form/CustomerForm.vue'), component: () => import('/@/views/demo/form/CustomerForm.vue'),
meta: { meta: {
title: 'rroutes.demo.form.customerForm', title: 'routes.demo.form.customerForm',
}, },
}, },
], ],

View File

@ -30,8 +30,6 @@ hotModuleUnregisterModule(NAME);
const { permissionCacheType } = useProjectSetting(); const { permissionCacheType } = useProjectSetting();
const { t } = useI18n('sys.app');
function getCache<T>(key: string) { function getCache<T>(key: string) {
const fn = permissionCacheType === CacheTypeEnum.LOCAL ? getLocal : getSession; const fn = permissionCacheType === CacheTypeEnum.LOCAL ? getLocal : getSession;
return fn(key) as T; return fn(key) as T;
@ -145,6 +143,7 @@ class User extends VuexModule {
@Action @Action
async confirmLoginOut() { async confirmLoginOut() {
const { createConfirm } = useMessage(); const { createConfirm } = useMessage();
const { t } = useI18n('sys.app');
createConfirm({ createConfirm({
iconType: 'warning', iconType: 'warning',
title: t('loginOutTip'), title: t('loginOutTip'),

View File

@ -3,10 +3,9 @@ import { userStore } from '/@/store/modules/user';
import { useI18n } from '/@/hooks/web/useI18n'; import { useI18n } from '/@/hooks/web/useI18n';
const { createMessage } = useMessage(); const { createMessage } = useMessage();
const { t } = useI18n('sys.api');
const error = createMessage.error!; const error = createMessage.error!;
export function checkStatus(status: number, msg: string): void { export function checkStatus(status: number, msg: string): void {
const { t } = useI18n('sys.api');
switch (status) { switch (status) {
case 400: case 400:
error(`${msg}`); error(`${msg}`);

View File

@ -22,7 +22,6 @@ import { errorStore } from '/@/store/modules/error';
import { errorResult } from './const'; import { errorResult } from './const';
import { useI18n } from '/@/hooks/web/useI18n'; import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('sys.api');
const globSetting = useGlobSetting(); const globSetting = useGlobSetting();
const prefix = globSetting.urlPrefix; const prefix = globSetting.urlPrefix;
const { createMessage, createErrorModal } = useMessage(); const { createMessage, createErrorModal } = useMessage();
@ -35,6 +34,7 @@ const transform: AxiosTransform = {
* @description: * @description:
*/ */
transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => { transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => {
const { t } = useI18n('sys.api');
const { isTransformRequestResult } = options; const { isTransformRequestResult } = options;
// 不进行任何处理,直接返回 // 不进行任何处理,直接返回
// 用于页面代码可能需要直接获取codedatamessage这些信息时开启 // 用于页面代码可能需要直接获取codedatamessage这些信息时开启
@ -154,6 +154,7 @@ const transform: AxiosTransform = {
* @description: * @description:
*/ */
responseInterceptorsCatch: (error: any) => { responseInterceptorsCatch: (error: any) => {
const { t } = useI18n('sys.api');
errorStore.setupErrorHandle(error); errorStore.setupErrorHandle(error);
const { response, code, message } = error || {}; const { response, code, message } = error || {};
const msg: string = const msg: string =

40
src/utils/propTypes.ts Normal file
View File

@ -0,0 +1,40 @@
import { CSSProperties, VNodeChild } from 'vue';
import { createTypes, VueTypeValidableDef, VueTypesInterface } from 'vue-types';
type VueNode = VNodeChild | JSX.Element;
type PropTypes = VueTypesInterface & {
readonly style: VueTypeValidableDef<CSSProperties>;
readonly VNodeChild: VueTypeValidableDef<VueNode>;
// readonly trueBool: VueTypeValidableDef<boolean>;
};
const propTypes = createTypes({
func: undefined,
bool: undefined,
string: undefined,
number: undefined,
object: undefined,
integer: undefined,
}) as PropTypes;
propTypes.extend([
{
name: 'style',
getter: true,
type: [String, Object],
default: undefined,
},
{
name: 'VNodeChild',
getter: true,
type: undefined,
},
// {
// name: 'trueBool',
// getter: true,
// type: Boolean,
// default: true,
// },
]);
export { propTypes };

View File

@ -11,7 +11,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import StrengthMeter from '/@/components/StrengthMeter/index'; import { StrengthMeter } from '/@/components/StrengthMeter';
export default defineComponent({ export default defineComponent({
components: { components: {
StrengthMeter, StrengthMeter,

View File

@ -11,7 +11,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, ref } from 'vue'; import { defineComponent, ref } from 'vue';
import { Alert } from 'ant-design-vue'; import { Alert } from 'ant-design-vue';
import ClickOutSide from '/@/components/ClickOutSide/index.vue'; import { ClickOutSide } from '/@/components/ClickOutSide';
export default defineComponent({ export default defineComponent({
components: { ClickOutSide, Alert }, components: { ClickOutSide, Alert },
setup() { setup() {

View File

@ -1,6 +1,6 @@
import { DescItem } from '/@/components/Description/index'; import { DescItem } from '/@/components/Description/index';
import { BasicColumn } from '/@/components/Table/src/types/table'; import { BasicColumn } from '/@/components/Table/src/types/table';
import Button from '/@/components/Button/index.vue'; import { Button } from '/@/components/Button';
import { Badge } from 'ant-design-vue'; import { Badge } from 'ant-design-vue';

View File

@ -16,23 +16,23 @@
</a-card> </a-card>
</div> </div>
<AppPageFooter> <PageFooter>
<template #right> <template #right>
<a-button type="primary" @click="submitAll">提交</a-button> <a-button type="primary" @click="submitAll">提交</a-button>
</template> </template>
</AppPageFooter> </PageFooter>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { BasicForm, useForm } from '/@/components/Form'; import { BasicForm, useForm } from '/@/components/Form';
import { defineComponent, ref } from 'vue'; import { defineComponent, ref } from 'vue';
import PersonTable from './PersonTable.vue'; import PersonTable from './PersonTable.vue';
import { AppPageFooter } from '/@/components/Application'; import { PageFooter } from '/@/components/Page';
import { schemas, taskSchemas } from './data'; import { schemas, taskSchemas } from './data';
export default defineComponent({ export default defineComponent({
components: { BasicForm, PersonTable, AppPageFooter }, components: { BasicForm, PersonTable, PageFooter },
setup() { setup() {
const tableRef = ref<{ getDataSource: () => any } | null>(null); const tableRef = ref<{ getDataSource: () => any } | null>(null);

View File

@ -63,7 +63,7 @@
import { defineComponent, reactive, ref, unref, toRaw } from 'vue'; import { defineComponent, reactive, ref, unref, toRaw } from 'vue';
import { Checkbox } from 'ant-design-vue'; import { Checkbox } from 'ant-design-vue';
import Button from '/@/components/Button/index.vue'; import { Button } from '/@/components/Button';
import { AppLocalePicker } from '/@/components/Application'; import { AppLocalePicker } from '/@/components/Application';
// import { BasicDragVerify, DragVerifyActionType } from '/@/components/Verify/index'; // import { BasicDragVerify, DragVerifyActionType } from '/@/components/Verify/index';

View File

@ -8318,7 +8318,7 @@ vue-router@^4.0.0-rc.5:
resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.0.0-rc.5.tgz#191d32e3d5276641ff21e881d34e33a71dc6e8f0" resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.0.0-rc.5.tgz#191d32e3d5276641ff21e881d34e33a71dc6e8f0"
integrity sha512-Q8Tt6VGwGMN5qASeIdjSydU3uRADK9AUkqnbnzmTz+zZKS0W6GZOAuP235lf3y5/MqEFSKRJGaTWPEY0t+Rjmg== integrity sha512-Q8Tt6VGwGMN5qASeIdjSydU3uRADK9AUkqnbnzmTz+zZKS0W6GZOAuP235lf3y5/MqEFSKRJGaTWPEY0t+Rjmg==
vue-types@^3.0.0: vue-types@^3.0.0, vue-types@^3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.npmjs.org/vue-types/-/vue-types-3.0.1.tgz#20e9baae8673de8093d0a989234695d08d544be0" resolved "https://registry.npmjs.org/vue-types/-/vue-types-3.0.1.tgz#20e9baae8673de8093d0a989234695d08d544be0"
integrity sha512-UbvbzPu8DNzZRfMB1RDTFKBB6seMm80scMFdP+GkKaw00EugC3cjq9AtlS4y258vDkpAe9HfqbRO4cp63qVHXQ== integrity sha512-UbvbzPu8DNzZRfMB1RDTFKBB6seMm80scMFdP+GkKaw00EugC3cjq9AtlS4y258vDkpAe9HfqbRO4cp63qVHXQ==