u-mask.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <template>
  2. <view
  3. class="u-mask"
  4. hover-stop-propagation
  5. :style="[maskStyle, zoomStyle]"
  6. @tap.stop="click"
  7. @touchmove.stop.prevent="() => {}"
  8. :class="{
  9. 'u-mask-zoom': zoom,
  10. 'u-mask-show': show
  11. }"
  12. >
  13. <slot />
  14. </view>
  15. </template>
  16. <script>
  17. /**
  18. * mask 遮罩
  19. * @description 创建一个遮罩层,用于强调特定的页面元素,并阻止用户对遮罩下层的内容进行操作,一般用于弹窗场景
  20. * @tutorial https://www.uviewui.com/components/mask.html
  21. * @property {Boolean} show 是否显示遮罩(默认false)
  22. * @property {String Number} z-index z-index 层级(默认1070)
  23. * @property {Object} custom-style 自定义样式对象,见上方说明
  24. * @property {String Number} duration 动画时长,单位毫秒(默认300)
  25. * @property {Boolean} zoom 是否使用scale对遮罩进行缩放(默认true)
  26. * @property {Boolean} mask-click-able 遮罩是否可点击,为false时点击不会发送click事件(默认true)
  27. * @event {Function} click mask-click-able为true时,点击遮罩发送此事件
  28. * @example <u-mask :show="show" @click="show = false"></u-mask>
  29. */
  30. export default {
  31. name: 'u-mask',
  32. props: {
  33. // 是否显示遮罩
  34. show: {
  35. type: Boolean,
  36. default: false
  37. },
  38. // 层级z-index
  39. zIndex: {
  40. type: [Number, String],
  41. default: ''
  42. },
  43. // 用户自定义样式
  44. customStyle: {
  45. type: Object,
  46. default() {
  47. return {};
  48. }
  49. },
  50. // 遮罩的动画样式, 是否使用使用zoom进行scale进行缩放
  51. zoom: {
  52. type: Boolean,
  53. default: true
  54. },
  55. // 遮罩的过渡时间,单位为ms
  56. duration: {
  57. type: [Number, String],
  58. default: 300
  59. },
  60. // 是否可以通过点击遮罩进行关闭
  61. maskClickAble: {
  62. type: Boolean,
  63. default: true
  64. }
  65. },
  66. data() {
  67. return {
  68. zoomStyle: {
  69. transform: ''
  70. },
  71. scale: 'scale(1.2, 1.2)'
  72. };
  73. },
  74. watch: {
  75. show(n) {
  76. if (n && this.zoom) {
  77. // 当展示遮罩的时候,设置scale为1,达到缩小(原来为1.2)的效果
  78. this.zoomStyle.transform = 'scale(1, 1)';
  79. } else if (!n && this.zoom) {
  80. // 当隐藏遮罩的时候,设置scale为1.2,达到放大(因为显示遮罩时已重置为1)的效果
  81. this.zoomStyle.transform = this.scale;
  82. }
  83. }
  84. },
  85. computed: {
  86. maskStyle() {
  87. let style = {};
  88. style.backgroundColor = 'rgba(0, 0, 0, 0.6)';
  89. if (this.show) style.zIndex = this.zIndex ? this.zIndex : this.$u.zIndex.mask;
  90. else style.zIndex = -1;
  91. style.transition = `all ${this.duration / 1000}s ease-in-out`;
  92. // 判断用户传递的对象是否为空,不为空就进行合并
  93. if (Object.keys(this.customStyle).length)
  94. style = {
  95. ...style,
  96. ...this.customStyle
  97. };
  98. return style;
  99. }
  100. },
  101. methods: {
  102. click() {
  103. if (!this.maskClickAble) return;
  104. this.$emit('click');
  105. }
  106. }
  107. };
  108. </script>
  109. <style lang="scss" scoped>
  110. @import '../../libs/css/style.components.scss';
  111. .u-mask {
  112. position: fixed;
  113. top: 0;
  114. left: 0;
  115. right: 0;
  116. bottom: 0;
  117. opacity: 0;
  118. pointer-events: auto;
  119. transition: transform 0.3s;
  120. }
  121. .u-mask-show {
  122. opacity: 1;
  123. }
  124. .u-mask-zoom {
  125. transform: scale(1.2, 1.2);
  126. }
  127. </style>