index.ts 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { inject, provide, reactive, ref } from 'vue'
  2. import type { NotifyProps } from './types'
  3. import { deepMerge, isString } from '../common/util'
  4. let timer: ReturnType<typeof setTimeout>
  5. let currentOptions = getDefaultOptions()
  6. const notifyDefaultOptionKey = '__NOTIFY_OPTION__'
  7. const None = Symbol('None')
  8. export const setNotifyDefaultOptions = (options: NotifyProps) => {
  9. currentOptions = deepMerge(currentOptions, options) as NotifyProps
  10. }
  11. export const resetNotifyDefaultOptions = () => {
  12. currentOptions = getDefaultOptions()
  13. }
  14. export const useNotify = (selector: string = '') => {
  15. const notifyOptionKey = getNotifyOptionKey(selector)
  16. const notifyOption = inject(notifyOptionKey, ref<NotifyProps | typeof None>(None))
  17. if (notifyOption.value === None) {
  18. notifyOption.value = currentOptions
  19. provide(notifyOptionKey, notifyOption)
  20. }
  21. const showNotify = (option: NotifyProps | string) => {
  22. const options = deepMerge(currentOptions, isString(option) ? { message: option } : option) as NotifyProps
  23. notifyOption.value = deepMerge(options, { visible: true })
  24. if (notifyOption.value.duration && notifyOption.value.duration > 0) {
  25. timer && clearTimeout(timer)
  26. timer = setTimeout(() => closeNotify(), options.duration)
  27. }
  28. }
  29. const closeNotify = () => {
  30. timer && clearTimeout(timer)
  31. if (notifyOption.value !== None) {
  32. notifyOption.value.visible = false
  33. }
  34. }
  35. return {
  36. showNotify,
  37. closeNotify
  38. }
  39. }
  40. export const getNotifyOptionKey = (selector: string) => {
  41. return selector ? `${notifyDefaultOptionKey}${selector}` : notifyDefaultOptionKey
  42. }
  43. function getDefaultOptions(): NotifyProps {
  44. return {
  45. type: 'danger',
  46. color: undefined,
  47. zIndex: 99,
  48. message: '',
  49. duration: 3000,
  50. position: 'top',
  51. safeHeight: undefined,
  52. background: undefined,
  53. onClick: undefined,
  54. onClosed: undefined,
  55. onOpened: undefined
  56. }
  57. }