You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

u-mask.vue 3.1 KiB

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