wd-notify.vue 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <template>
  2. <wd-popup
  3. v-model="state.visible"
  4. :custom-style="customStyle"
  5. :position="state.position"
  6. :z-index="state.zIndex"
  7. :duration="250"
  8. :modal="false"
  9. :root-portal="state.rootPortal"
  10. @leave="onClosed"
  11. @enter="onOpened"
  12. >
  13. <view class="wd-notify" :class="[`wd-notify--${state.type}`]" :style="{ color: state.color, background: state.background }" @click="onClick">
  14. <slot>{{ state.message }}</slot>
  15. </view>
  16. </wd-popup>
  17. </template>
  18. <script lang="ts">
  19. export default {
  20. name: 'wd-notify',
  21. options: {
  22. virtualHost: true,
  23. addGlobalClass: true,
  24. styleIsolation: 'shared'
  25. }
  26. }
  27. </script>
  28. <script lang="ts" setup>
  29. import wdPopup from '../wd-popup/wd-popup.vue'
  30. import { inject, computed, watch, ref } from 'vue'
  31. import { notifyProps, type NotifyProps } from './types'
  32. import { getNotifyOptionKey } from '.'
  33. import { addUnit, isFunction } from '../common/util'
  34. const props = defineProps(notifyProps)
  35. const emits = defineEmits<{
  36. (e: 'update:visible', value: boolean): void
  37. (e: 'click', event: MouseEvent): void
  38. (e: 'closed'): void
  39. (e: 'opened'): void
  40. }>()
  41. const state = inject(getNotifyOptionKey(props.selector), ref<NotifyProps>(props))
  42. const customStyle = computed(() => {
  43. const { safeHeight, position } = state.value
  44. let customStyle: string = ''
  45. switch (position) {
  46. case 'top':
  47. customStyle = `top: calc(var(--window-top) + ${addUnit(safeHeight || 0)})`
  48. break
  49. case 'bottom':
  50. customStyle = 'bottom: var(--window-bottom)'
  51. break
  52. default:
  53. break
  54. }
  55. return customStyle
  56. })
  57. const onClick = (event: MouseEvent) => {
  58. if (isFunction(state.value.onClick)) return state.value.onClick(event)
  59. emits('click', event)
  60. }
  61. const onClosed = () => {
  62. if (isFunction(state.value.onClosed)) return state.value.onClosed()
  63. emits('closed')
  64. }
  65. const onOpened = () => {
  66. if (isFunction(state.value.onOpened)) return state.value.onOpened()
  67. emits('opened')
  68. }
  69. watch(
  70. () => state.value.visible,
  71. (visible) => {
  72. emits('update:visible', visible as boolean)
  73. },
  74. { deep: true }
  75. )
  76. </script>
  77. <style lang="scss" scoped>
  78. @import './index.scss';
  79. </style>