Skip to content

Commit

Permalink
feat: 封装新的 message hook 🏷️🏷️🏷️
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyh2001 committed Jan 29, 2023
1 parent e2a2b29 commit 8dd4192
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 205 deletions.
1 change: 1 addition & 0 deletions packages/fighting-design/_hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from './use-visible'
export * from './use-tabs-nav-style'
export * from './use-button'
export * from './use-tips'
export * from './use-eject'
129 changes: 129 additions & 0 deletions packages/fighting-design/_hooks/use-eject/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { useList, useTips } from '..'
import { onMounted, nextTick, ref, computed } from 'vue'
import type { Ref, CSSProperties } from 'vue'
import type { MessageProps } from '../../message'
import type { NotificationProps } from '../../notification'
import type { UseEjectReturn } from './interface'

export * from './interface.d'

/**
* 针对 message notification 组件公共方法封装
*
* @param prop props 参数
* @param component 组件名
* @param el 元素节点
*/
export const useEject = (
prop: MessageProps | NotificationProps,
component: 'message' | 'notification',
el: Ref<HTMLDivElement | null>
): UseEjectReturn => {

/** 元素的高度 */
const elHeight = ref<number>(0)

/** 控制显示隐藏 */
const visible = ref<boolean>(false)

/** 计时器 */
const timer = ref<NodeJS.Timeout>()

const { classes, styles } = useList(prop, component)
const { getSiblingOffset, removeInstance } = useTips()

/** 类名列表 */
const classList = classes(['type', 'placement', 'round'], `f-${component}`)

/** 样式列表 */
const styleList = styles(['color', 'background', 'zIndex'], 'zIndex')

onMounted((): void => {
nextTick((): void => {
/**
* 设置元素的高度
*
* @see getBoundingClientRec https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRec
*/
elHeight.value = el.value ? el.value.getBoundingClientRect().height : 0
})
})

/** 判断方位 */
const isPosition = computed((): boolean => prop.placement.includes(component === 'message' ? 'top' : 'right'))

/** 计算组件之间偏移量 */
const siblingOffset = computed((): number => getSiblingOffset(prop.placement, prop.id, !isPosition.value))

/** 计算偏移量 */
const offset = computed((): number => prop.offset + siblingOffset.value)

/** 底部偏移量 */
const bottom = computed((): number => elHeight.value + offset.value)

/** 位置偏移量样式列表 */
const offsetStyle = computed((): CSSProperties => {
const styles: CSSProperties = {}

if (prop.placement.includes('bottom')) {
styles.bottom = offset.value + 'px'
} else {
styles.top = offset.value + 'px'
}

return styles
})

/** 清除计时器 */
const clearTimer = (): void => {
if (!timer.value) return
clearTimeout(timer.value)
}

/** 关闭提示框 */
const closeMessage = (): void => {
clearTimer()
visible.value = false
}

/**
* 关闭提示框之后的回调
*
* 移除组件实例
*/
const closeMessageEnd = (): void => {
removeInstance(prop.placement, prop.id)
}

/**
* 开始计时
*
* 到时间隐藏提示框
*/
const startTime = (): void => {
if (!prop.duration) return
timer.value = setTimeout((): void => {
closeMessage()
}, prop.duration)
}

/** 初始化之后开始计时 并且展示提示 */
onMounted((): void => {
startTime()
visible.value = true
})

return {
classList,
styleList,
elHeight,
bottom,
offsetStyle,
isPosition,
visible,
clearTimer,
closeMessage,
closeMessageEnd,
startTime
}
}
31 changes: 31 additions & 0 deletions packages/fighting-design/_hooks/use-eject/interface.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { ComputedRef, CSSProperties, Ref } from 'vue'
import type { ClassList } from '../../_interface'

/**
* useEject 返回值类型接口
*
* @param classList 类名列表
* @param styleList 样式列表
* @param elHeight 元素的高度
* @param bottom 底部偏移量
* @param offsetStyle 位置偏移量样式列表
* @param isPosition 判断方位
* @param visible 控制显示隐藏
* @param clearTimer 清除计时器
* @param closeMessage 关闭提示框
* @param closeMessageEnd 关闭提示框之后的回调
* @param startTime 开始计时
*/
export interface UseEjectReturn {
classList: ComputedRef<ClassList>
styleList: ComputedRef<CSSProperties>
elHeight: Ref<number>
bottom: ComputedRef<number>
offsetStyle: ComputedRef<CSSProperties>
isPosition: ComputedRef<boolean>
visible: Ref<boolean>
clearTimer: () => void
closeMessage: () => void
closeMessageEnd: () => void
startTime: () => void
}
110 changes: 16 additions & 94 deletions packages/fighting-design/message/src/message.vue
Original file line number Diff line number Diff line change
@@ -1,110 +1,32 @@
<script lang="ts" setup name="FMessage">
import { Props } from './props'
import { computed, onMounted, ref, isVNode, nextTick } from 'vue'
import { ref, isVNode } from 'vue'
import { FSvgIcon } from '../../svg-icon'
import { FCloseBtn } from '../../close-btn'
import { isString } from '../../_utils'
import { useList, useTips } from '../../_hooks'
import type { CSSProperties, Ref } from 'vue'
import { useEject } from '../../_hooks'
import type { Ref } from 'vue'
const prop = defineProps(Props)
const emit = defineEmits({
destroy: (): boolean => true
})
const { getSiblingOffset, removeInstance } = useTips()
const { classes, styles } = useList(prop, 'message')
/** 元素节点 */
const FMessageEl: Ref<HTMLDivElement | null> = ref<HTMLDivElement | null>(null)
/** message 元素的高度 */
const messageHeight = ref<number>(0)
/** 是否展示 */
const visible = ref<boolean>(false)
/** 判断是否为上面方位的 */
const isTop = computed((): boolean => prop.placement === 'top')
/** 计算组件之间偏移量 */
const siblingOffset = computed((): number => getSiblingOffset(prop.placement, prop.id, !isTop.value))
/** 计算偏移量 */
const offset = computed((): number => prop.offset + siblingOffset.value)
/** 底部偏移量 */
const bottom = computed((): number => messageHeight.value + offset.value)
onMounted((): void => {
nextTick((): void => {
/**
* 设置元素的高度
*
* @see getBoundingClientRec https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRec
*/
messageHeight.value = FMessageEl.value ? FMessageEl.value.getBoundingClientRect().height : 0
})
})
/** 类名列表 */
const classList = classes(['type', 'placement', 'round'], 'f-message')
/** 样式列表 */
const styleList = styles(['color', 'background', 'zIndex'], 'zIndex')
/** 位置偏移量样式列表 */
const offsetStyle = computed((): CSSProperties => {
const styles: CSSProperties = {}
if (prop.placement.includes('bottom')) {
styles.bottom = offset.value + 'px'
} else {
styles.top = offset.value + 'px'
}
return styles
})
/** 计时器 */
const timer = ref<NodeJS.Timeout>()
/** 清除计时器 */
const clearTimer = (): void => {
if (!timer.value) return
clearTimeout(timer.value)
}
/** 关闭提示框 */
const closeMessage = (): void => {
clearTimer()
visible.value = false
}
/**
* 关闭提示框之后的回调
*
* 移除组件实例
*/
const closeMessageEnd = (): void => {
removeInstance(prop.placement, prop.id)
}
/**
* 开始计时
*
* 到时间隐藏提示框
*/
const startTime = (): void => {
if (!prop.duration) return
timer.value = setTimeout((): void => {
closeMessage()
}, prop.duration)
}
/** 初始化之后开始计时 并且展示提示 */
onMounted((): void => {
startTime()
visible.value = true
})
const {
classList,
styleList,
bottom,
offsetStyle,
isPosition,
visible,
clearTimer,
closeMessage,
closeMessageEnd,
startTime
} = useEject(prop, 'message', FMessageEl)
defineExpose({
visible,
Expand All @@ -116,7 +38,7 @@
<template>
<transition
mode="out-in"
:name="`f-message-fade` + (isTop ? '-top' : '-bottom')"
:name="`f-message-fade` + (isPosition ? '-top' : '-bottom')"
@before-leave="closeMessageEnd"
@after-leave="emit('destroy')"
>
Expand Down
Loading

0 comments on commit 8dd4192

Please sign in to comment.