u-mask.vue 3.4 KB

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