fs-popup.vue 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <template>
  2. <view class="fs-popup">
  3. <view class="fs-popup-drawer" :class="[direction, { show: modelValue }]" :style="[style, customStyle]">
  4. <slot></slot>
  5. </view>
  6. <fs-mask v-if="showMask" :modelValue="modelValue" @close="handleClose" :maskClickable="maskClickable"></fs-mask>
  7. </view>
  8. </template>
  9. <script>
  10. /**
  11. * 弹出层组件
  12. * @description 弹出层组件
  13. * @property {String} direction = [left | right | top | bottom] 弹出位置
  14. * @property {Boolean} showMask 是否显示遮罩
  15. * @property {Boolean} maskClickable 遮罩是否可点击
  16. * @property {String} width 弹出层宽度(仅direction为left\right有效)
  17. * @property {String} height 弹出层高度(仅direction为top\bottom有效)
  18. * @property {Object} customStyle 自定义样式
  19. */
  20. export default {
  21. name: 'fs-popup'
  22. }
  23. </script>
  24. <script setup>
  25. import { computed } from 'vue'
  26. const props = defineProps({
  27. modelValue: Boolean,
  28. direction: {
  29. type: String,
  30. default: 'left',
  31. validator(value) {
  32. return ['left', 'right', 'top', 'bottom'].includes(value)
  33. }
  34. },
  35. width: {
  36. type: String,
  37. default: '80%'
  38. },
  39. height: {
  40. type: String,
  41. default: '30%'
  42. },
  43. showMask: {
  44. type: Boolean,
  45. default: true
  46. },
  47. maskClickable: {
  48. type: Boolean,
  49. default: true
  50. },
  51. customStyle: {
  52. type: Object,
  53. default() {
  54. return {}
  55. }
  56. }
  57. })
  58. const style = computed(() => {
  59. let ret = ''
  60. if (props.direction === 'left' || props.direction === 'right') {
  61. ret = `width: ${props.width}`
  62. } else {
  63. ret = `height: ${props.height}`
  64. }
  65. return ret
  66. })
  67. const emits = defineEmits(['update:modelValue'])
  68. const handleClose = () => {
  69. emits('update:modelValue', false)
  70. }
  71. </script>
  72. <style lang="scss" scoped>
  73. .fs-popup {
  74. &-drawer {
  75. position: fixed;
  76. background-color: #fff;
  77. z-index: 900;
  78. transition: all 0.3s;
  79. overflow: auto;
  80. }
  81. .left {
  82. top: var(--window-top);
  83. bottom: var(--window-bottom);
  84. left: 0;
  85. transform: translateX(-100%);
  86. }
  87. .right {
  88. top: var(--window-top);
  89. bottom: var(--window-bottom);
  90. right: 0;
  91. transform: translateX(100%);
  92. }
  93. .top {
  94. top: var(--window-top);
  95. right: 0;
  96. left: 0;
  97. transform: translateY(-200%);
  98. }
  99. .bottom {
  100. left: 0;
  101. bottom: var(--window-bottom);
  102. right: 0;
  103. transform: translateY(100%);
  104. }
  105. .show {
  106. transform: translateX(0);
  107. }
  108. }
  109. </style>