Browse Source

fix: type

main
xingyu 2 years ago
parent
commit
cb132248c6
  1. 10
      src/components/FormDesign/src/components/VFormDesign/components/ComponentProps.vue
  2. 2
      src/components/FormDesign/src/components/VFormDesign/components/FormItemColumnProps.vue
  3. 3
      src/components/FormDesign/src/components/VFormDesign/components/FormItemProps.vue
  4. 13
      src/components/Scrollbar/src/util.ts
  5. 19
      src/components/SimpleMenu/src/components/Menu.vue
  6. 2
      src/components/SimpleMenu/src/components/SubMenuItem.vue
  7. 2
      src/components/Tree/src/types/tree.ts
  8. 14
      src/hooks/web/useMessage.tsx
  9. 7
      src/layouts/default/header/components/notify/NoticeList.vue
  10. 8
      src/logics/mitt/routeChange.ts
  11. 90
      src/utils/mitt.ts
  12. 23
      src/utils/types.ts

10
src/components/FormDesign/src/components/VFormDesign/components/ComponentProps.vue

@ -141,14 +141,18 @@ const linkOptions = computed(() => {
<!-- 处理数组属性placeholder --> <!-- 处理数组属性placeholder -->
<div v-if="item.children"> <div v-if="item.children">
<template v-for="(child, index) of item.children" :key="index">
<component <component
v-bind="child.componentProps" :is="child.component" v-for="(child, index) of item.children" v-bind="child.componentProps"
:key="index" v-model:value="formConfig.currentItem.componentProps[item.name][index]" :is="child.component"
v-if="child.component"
v-model:value="formConfig.currentItem.componentProps[item.name][index]"
/> />
</template>
</div> </div>
<!-- 如果不是数组则正常处理属性值 --> <!-- 如果不是数组则正常处理属性值 -->
<component <component
v-bind="item.componentProps" :is="item.component" v-else v-bind="item.componentProps" :is="item.component" v-else-if="item.component"
v-model:value="formConfig.currentItem.componentProps[item.name]" class="component-prop" v-model:value="formConfig.currentItem.componentProps[item.name]" class="component-prop"
/> />
</FormItem> </FormItem>

2
src/components/FormDesign/src/components/VFormDesign/components/FormItemColumnProps.vue

@ -25,7 +25,7 @@ function showProps(exclude: string[] | undefined) {
<div v-for="item of baseItemColumnProps" :key="item.name"> <div v-for="item of baseItemColumnProps" :key="item.name">
<FormItem v-if="showProps(item.exclude)" :label="item.label"> <FormItem v-if="showProps(item.exclude)" :label="item.label">
<component <component
v-bind="item.componentProps" :is="item.component" v-if="formConfig.currentItem.colProps" v-bind="item.componentProps" :is="item.component" v-if="formConfig.currentItem.colProps && item.component"
v-model:value="formConfig.currentItem.colProps[item.name]" class="component-props" v-model:value="formConfig.currentItem.colProps[item.name]" class="component-props"
/> />
</FormItem> </FormItem>

3
src/components/FormDesign/src/components/VFormDesign/components/FormItemProps.vue

@ -56,6 +56,7 @@ const controlPropsList = computed(() => {
<component <component
v-bind="item.componentProps" v-bind="item.componentProps"
:is="item.component" :is="item.component"
v-if="item.component"
v-model:value="formConfig.currentItem[item.name]" v-model:value="formConfig.currentItem[item.name]"
class="component-props" class="component-props"
/> />
@ -66,6 +67,7 @@ const controlPropsList = computed(() => {
<component <component
v-bind="item.componentProps" v-bind="item.componentProps"
:is="item.component" :is="item.component"
v-if="item.component"
v-model:value="formConfig.currentItem.itemProps[item.name]" v-model:value="formConfig.currentItem.itemProps[item.name]"
class="component-props" class="component-props"
/> />
@ -75,6 +77,7 @@ const controlPropsList = computed(() => {
<component <component
v-bind="item.componentProps" v-bind="item.componentProps"
:is="item.component" :is="item.component"
v-if="item.component"
v-model:value="formConfig.currentItem.itemProps[item.name].span" v-model:value="formConfig.currentItem.itemProps[item.name].span"
class="component-props" class="component-props"
/> />

13
src/components/Scrollbar/src/util.ts

@ -1,4 +1,5 @@
import type { BarMap } from './types' import type { BarMap } from './types'
import type { MergeAll } from '@/utils/types'
export const BAR_MAP: BarMap = { export const BAR_MAP: BarMap = {
vertical: { vertical: {
@ -39,8 +40,16 @@ function extend<T extends object, K extends object>(to: T, _from: K): T & K {
return Object.assign(to as any, _from) return Object.assign(to as any, _from)
} }
export function toObject<T extends object>(arr: Array<T>): Recordable<T> { /**
const res = {} * [
* { name: 'zhangsan', age: 18 },
* { sex: 'male', age: 20 }
* ]
* =>
* { name: 'zhangsan', sex: 'male', age: 20 }
*/
export function toObject<T extends object[]>(arr: T): MergeAll<T> {
const res = {} as MergeAll<T>
for (let i = 0; i < arr.length; i++) { for (let i = 0; i < arr.length; i++) {
if (arr[i]) if (arr[i])
extend(res, arr[i]) extend(res, arr[i])

19
src/components/SimpleMenu/src/components/Menu.vue

@ -4,7 +4,7 @@ import type { SubMenuProvider } from './types'
import { createSimpleRootMenuContext } from './useSimpleMenuContext' import { createSimpleRootMenuContext } from './useSimpleMenuContext'
import { useDesign } from '@/hooks/web/useDesign' import { useDesign } from '@/hooks/web/useDesign'
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import mitt from '@/utils/mitt' import { mitt } from '@/utils/mitt'
// eslint-disable-next-line vue/no-reserved-component-names // eslint-disable-next-line vue/no-reserved-component-names
defineOptions({ name: 'Menu' }) defineOptions({ name: 'Menu' })
@ -28,11 +28,18 @@ const props = defineProps({
}) })
const emit = defineEmits(['select', 'open-change']) const emit = defineEmits(['select', 'open-change'])
const rootMenuEmitter = mitt() const rootMenuEmitter = mitt<{
'on-update-opened': (string | number)[]
'on-menu-item-select': string | number
'open-name-change': {
name: string
opened: boolean
}
}>()
const instance = getCurrentInstance() const instance = getCurrentInstance()
const currentActiveName = ref<string | number>('') const currentActiveName = ref<string | number>('')
const openedNames = ref<string[]>([]) const openedNames = ref<(string | number)[]>([])
const { prefixCls } = useDesign('menu') const { prefixCls } = useDesign('menu')
@ -77,14 +84,14 @@ function updateOpened() {
rootMenuEmitter.emit('on-update-opened', openedNames.value) rootMenuEmitter.emit('on-update-opened', openedNames.value)
} }
function addSubMenu(name: string) { function addSubMenu(name: string | number) {
if (openedNames.value.includes(name)) if (openedNames.value.includes(name))
return return
openedNames.value.push(name) openedNames.value.push(name)
updateOpened() updateOpened()
} }
function removeSubMenu(name: string) { function removeSubMenu(name: string | number) {
openedNames.value = openedNames.value.filter(item => item !== name) openedNames.value = openedNames.value.filter(item => item !== name)
updateOpened() updateOpened()
} }
@ -115,7 +122,7 @@ provide<SubMenuProvider>(`subMenu:${instance?.uid}`, {
onMounted(() => { onMounted(() => {
openedNames.value = !props.collapse ? [...props.openNames] : [] openedNames.value = !props.collapse ? [...props.openNames] : []
updateOpened() updateOpened()
rootMenuEmitter.on('on-menu-item-select', (name: string) => { rootMenuEmitter.on('on-menu-item-select', (name: string | number) => {
currentActiveName.value = name currentActiveName.value = name
nextTick(() => { nextTick(() => {

2
src/components/SimpleMenu/src/components/SubMenuItem.vue

@ -10,7 +10,7 @@ import { propTypes } from '@/utils/propTypes'
import { CollapseTransition } from '@/components/Transition' import { CollapseTransition } from '@/components/Transition'
import { Icon } from '@/components/Icon' import { Icon } from '@/components/Icon'
import { isBoolean, isObject } from '@/utils/is' import { isBoolean, isObject } from '@/utils/is'
import mitt from '@/utils/mitt' import { mitt } from '@/utils/mitt'
defineOptions({ name: 'SubMenu' }) defineOptions({ name: 'SubMenu' })

2
src/components/Tree/src/types/tree.ts

@ -37,7 +37,7 @@ export const treeProps = buildProps({
}, },
renderIcon: { renderIcon: {
type: Function as PropType<(params: Recordable) => string>, type: Function as PropType<(...params: any[]) => string>,
}, },
helpMessage: { helpMessage: {

14
src/hooks/web/useMessage.tsx

@ -1,4 +1,4 @@
import type { ModalFunc, ModalFuncProps } from 'ant-design-vue/lib/modal/Modal' import type { ModalFuncProps } from 'ant-design-vue/lib/modal/Modal'
import { message as Message, Modal, notification } from 'ant-design-vue' import { message as Message, Modal, notification } from 'ant-design-vue'
import { CheckCircleFilled, CloseCircleFilled, InfoCircleFilled } from '@ant-design/icons-vue' import { CheckCircleFilled, CloseCircleFilled, InfoCircleFilled } from '@ant-design/icons-vue'
@ -26,14 +26,6 @@ export interface ModalOptionsEx extends Omit<ModalFuncProps, 'iconType'> {
} }
export type ModalOptionsPartial = Partial<ModalOptionsEx> & Pick<ModalOptionsEx, 'content'> export type ModalOptionsPartial = Partial<ModalOptionsEx> & Pick<ModalOptionsEx, 'content'>
interface ConfirmOptions {
info: ModalFunc
success: ModalFunc
error: ModalFunc
warn: ModalFunc
warning: ModalFunc
}
function getIcon(iconType: string) { function getIcon(iconType: string) {
if (iconType === 'warning') if (iconType === 'warning')
return <InfoCircleFilled class="modal-icon-warning" /> return <InfoCircleFilled class="modal-icon-warning" />
@ -55,7 +47,7 @@ function renderContent({ content }: Pick<ModalOptionsEx, 'content'>) {
/** /**
* @description: Create confirmation box * @description: Create confirmation box
*/ */
function createConfirm(options: ModalOptionsEx): ConfirmOptions { function createConfirm(options: ModalOptionsEx) {
const iconType = options.iconType || 'warning' const iconType = options.iconType || 'warning'
Reflect.deleteProperty(options, 'iconType') Reflect.deleteProperty(options, 'iconType')
const opt: ModalFuncProps = { const opt: ModalFuncProps = {
@ -64,7 +56,7 @@ function createConfirm(options: ModalOptionsEx): ConfirmOptions {
...options, ...options,
content: renderContent(options), content: renderContent(options),
} }
return Modal.confirm(opt) as unknown as ConfirmOptions return Modal.confirm(opt)
} }
function getBaseOptions() { function getBaseOptions() {

7
src/layouts/default/header/components/notify/NoticeList.vue

@ -47,10 +47,13 @@ watch(
const isTitleClickable = computed(() => !!props.onTitleClick) const isTitleClickable = computed(() => !!props.onTitleClick)
const getPagination = computed(() => { const getPagination = computed(() => {
const { list, pageSize } = props const { list, pageSize } = props
if (isNumber(pageSize) && pageSize > 0 && list && list.length > pageSize) { // compatible line 104
// if typeof pageSize is boolean, Number(true) && 5 = 5, Number(false) && 5 = 0
const size = isNumber(pageSize) ? pageSize : Number(pageSize) && 5
if (size > 0 && list && list.length > size) {
return { return {
total: list.length, total: list.length,
pageSize, pageSize: size,
// size: 'small', // size: 'small',
current: unref(current), current: unref(current),
onChange(page) { onChange(page) {

8
src/logics/mitt/routeChange.ts

@ -3,13 +3,15 @@
*/ */
import type { RouteLocationNormalized } from 'vue-router' import type { RouteLocationNormalized } from 'vue-router'
import mitt from '@/utils/mitt' import { mitt } from '@/utils/mitt'
import { getRawRoute } from '@/utils' import { getRawRoute } from '@/utils'
const emitter = mitt()
const key = Symbol('route-change') const key = Symbol('route-change')
const emitter = mitt<{
[key]: RouteLocationNormalized
}>()
let lastChangeTab: RouteLocationNormalized let lastChangeTab: RouteLocationNormalized
export function setRouteChange(lastChangeRoute: RouteLocationNormalized) { export function setRouteChange(lastChangeRoute: RouteLocationNormalized) {

90
src/utils/mitt.ts

@ -1,34 +1,38 @@
/* eslint-disable array-callback-return */
/** /**
* copy to https://github.com/developit/mitt * copy to https://github.com/developit/mitt
* Expand clear method * Expand clear method
*/ */
export type EventType = string | symbol export type EventType = string | symbol
// An event handler can take an optional event argument // An event handler can take an optional event argument
// and should not return a value // and should not return a value
export type Handler<T = any> = (event?: T) => void export type Handler<T = unknown> = (event: T) => void
export type WildcardHandler = (type: EventType, event?: any) => void export type WildcardHandler<T = Record<string, unknown>> = (
type: keyof T,
event: T[keyof T],
) => void
// An array of all currently registered event handlers for a type // An array of all currently registered event handlers for a type
export type EventHandlerList = Array<Handler> export type EventHandlerList<T = unknown> = Array<Handler<T>>
export type WildCardEventHandlerList = Array<WildcardHandler> export type WildCardEventHandlerList<T = Record<string, unknown>> = Array<WildcardHandler<T>>
// A map of event types and their corresponding event handlers. // A map of event types and their corresponding event handlers.
export type EventHandlerMap = Map<EventType, EventHandlerList | WildCardEventHandlerList> export type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<
keyof Events | '*',
EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>
>
export interface Emitter { export interface Emitter<Events extends Record<EventType, unknown>> {
all: EventHandlerMap all: EventHandlerMap<Events>
on<T = any>(type: EventType, handler: Handler<T>): void on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void
on(type: '*', handler: WildcardHandler): void on(type: '*', handler: WildcardHandler<Events>): void
off<T = any>(type: EventType, handler: Handler<T>): void off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void
off(type: '*', handler: WildcardHandler): void off(type: '*', handler: WildcardHandler<Events>): void
emit<T = any>(type: EventType, event?: T): void emit<Key extends keyof Events>(type: Key, event: Events[Key]): void
emit(type: '*', event?: any): void emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void
clear(): void clear(): void
} }
@ -37,7 +41,10 @@ export interface Emitter {
* @name mitt * @name mitt
* @returns {Mitt} * @returns {Mitt}
*/ */
export default function mitt(all?: EventHandlerMap): Emitter { export function mitt<Events extends Record<EventType, unknown>>(
all?: EventHandlerMap<Events>,
): Emitter<Events> {
type GenericEventHandler = Handler<Events[keyof Events]> | WildcardHandler<Events>
all = all || new Map() all = all || new Map()
return { return {
@ -48,46 +55,61 @@ export default function mitt(all?: EventHandlerMap): Emitter {
/** /**
* Register an event handler for the given type. * Register an event handler for the given type.
* @param {string|symbol} type Type of event to listen for, or `"*"` for all events * @param {string|symbol} type Type of event to listen for, or `'*'` for all events
* @param {Function} handler Function to call in response to given event * @param {Function} handler Function to call in response to given event
* @memberOf mitt * @memberOf mitt
*/ */
on<T = any>(type: EventType, handler: Handler<T>) { on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {
const handlers = all?.get(type) const handlers: Array<GenericEventHandler> | undefined = all!.get(type)
const added = handlers && handlers.push(handler) if (handlers)
if (!added) handlers.push(handler)
all?.set(type, [handler])
else
all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>)
}, },
/** /**
* Remove an event handler for the given type. * Remove an event handler for the given type.
* @param {string|symbol} type Type of event to unregister `handler` from, or `"*"` * If `handler` is omitted, all handlers of the given type are removed.
* @param {Function} handler Handler function to remove * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)
* @param {Function} [handler] Handler function to remove
* @memberOf mitt * @memberOf mitt
*/ */
off<T = any>(type: EventType, handler: Handler<T>) { off<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {
const handlers = all?.get(type) const handlers: Array<GenericEventHandler> | undefined = all!.get(type)
if (handlers) if (handlers) {
if (handler)
handlers.splice(handlers.indexOf(handler) >>> 0, 1) handlers.splice(handlers.indexOf(handler) >>> 0, 1)
else
all!.set(type, [])
}
}, },
/** /**
* Invoke all handlers for the given type. * Invoke all handlers for the given type.
* If present, `"*"` handlers are invoked after type-matched handlers. * If present, `'*'` handlers are invoked after type-matched handlers.
* *
* Note: Manually firing "*" handlers is not supported. * Note: Manually firing '*' handlers is not supported.
* *
* @param {string|symbol} type The event type to invoke * @param {string|symbol} type The event type to invoke
* @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler
* @memberOf mitt * @memberOf mitt
*/ */
emit<T = any>(type: EventType, evt: T) { emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {
;((all?.get(type) || []) as EventHandlerList).slice().map((handler) => { let handlers = all!.get(type)
handler(evt) if (handlers) {
(handlers as EventHandlerList<Events[keyof Events]>).slice().forEach((handler) => {
handler(evt as Events[Key])
}) })
;((all?.get('*') || [])).slice().map((handler) => { }
handler(type, evt)
handlers = all!.get('*')
if (handlers) {
(handlers as WildCardEventHandlerList<Events>).slice().forEach((handler) => {
handler(type, evt as Events[Key])
}) })
}
}, },
/** /**

23
src/utils/types.ts

@ -39,3 +39,26 @@ export type ComponentSize = 'large' | 'medium' | 'small' | 'mini'
export type StyleValue = string | CSSProperties | Array<StyleValue> export type StyleValue = string | CSSProperties | Array<StyleValue>
export type Mutable<T> = { -readonly [P in keyof T]: T[P] } export type Mutable<T> = { -readonly [P in keyof T]: T[P] }
type Merge<O extends object, T extends object> = {
[K in keyof O | keyof T]: K extends keyof T ? T[K] : K extends keyof O ? O[K] : never;
}
/**
* T = [
* { name: string; age: number; },
* { sex: 'male' | 'female'; age: string }
* ]
* =>
* MergeAll<T> = {
* name: string;
* sex: 'male' | 'female';
* age: string
* }
*/
export type MergeAll<T extends object[], R extends object = object> = T extends [
infer F extends object,
...infer Rest extends object[],
]
? MergeAll<Rest, Merge<R, F>>
: R