uni-drawer.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <template>
  2. <view
  3. v-if="visibleSync"
  4. :class="{
  5. 'uni-drawer--visible': showDrawer,
  6. 'uni-drawer--right': rightMode
  7. }"
  8. class="uni-drawer"
  9. @touchmove.stop.prevent="moveHandle"
  10. >
  11. <view class="uni-drawer__mask" @tap="close" />
  12. <view class="uni-drawer__content">
  13. <slot />
  14. </view>
  15. </view>
  16. </template>
  17. <script>
  18. export default {
  19. name: 'UniDrawer',
  20. props: {
  21. /**
  22. * 显示状态
  23. */
  24. visible: {
  25. type: Boolean,
  26. default: false
  27. },
  28. /**
  29. * 显示模式(左、右),只在初始化生效
  30. */
  31. mode: {
  32. type: String,
  33. default: ''
  34. },
  35. /**
  36. * 蒙层显示状态
  37. */
  38. mask: {
  39. type: Boolean,
  40. default: true
  41. }
  42. },
  43. data() {
  44. return {
  45. visibleSync: false,
  46. showDrawer: false,
  47. rightMode: false,
  48. closeTimer: null,
  49. watchTimer: null
  50. };
  51. },
  52. watch: {
  53. visible(val) {
  54. clearTimeout(this.watchTimer);
  55. setTimeout(() => {
  56. this.showDrawer = val;
  57. }, 100);
  58. if (this.visibleSync) {
  59. clearTimeout(this.closeTimer);
  60. }
  61. if (val) {
  62. this.visibleSync = val;
  63. } else {
  64. this.watchTimer = setTimeout(() => {
  65. this.visibleSync = val;
  66. }, 300);
  67. }
  68. }
  69. },
  70. created() {
  71. this.visibleSync = this.visible;
  72. setTimeout(() => {
  73. this.showDrawer = this.visible;
  74. }, 100);
  75. this.rightMode = this.mode === 'right';
  76. },
  77. methods: {
  78. close() {
  79. this.showDrawer = false;
  80. this.closeTimer = setTimeout(() => {
  81. this.visibleSync = false;
  82. this.$emit('close');
  83. }, 200);
  84. },
  85. moveHandle() {}
  86. }
  87. };
  88. </script>
  89. <style>
  90. @charset "UTF-8";
  91. .uni-drawer {
  92. display: block;
  93. position: fixed;
  94. top: 0;
  95. left: 0;
  96. right: 0;
  97. bottom: 0;
  98. overflow: hidden;
  99. visibility: hidden;
  100. z-index: 999;
  101. height: 100vh;;
  102. }
  103. .uni-drawer.uni-drawer--right .uni-drawer__content {
  104. left: auto;
  105. right: 0;
  106. transform: translatex(100%);
  107. }
  108. .uni-drawer.uni-drawer--visible {
  109. visibility: visible;
  110. }
  111. .uni-drawer.uni-drawer--visible .uni-drawer__content {
  112. transform: translatex(0);
  113. }
  114. .uni-drawer.uni-drawer--visible .uni-drawer__mask {
  115. display: block;
  116. opacity: 1;
  117. }
  118. .uni-drawer__mask {
  119. display: block;
  120. opacity: 0;
  121. position: absolute;
  122. top: 0;
  123. left: 0;
  124. width: 100%;
  125. height: 100%;
  126. background: rgba(0, 0, 0, 0.4);
  127. transition: opacity 0.3s;
  128. }
  129. .uni-drawer__content {
  130. display: block;
  131. position: absolute;
  132. overflow-y: scroll;
  133. top: 0;
  134. left: 0;
  135. height: 100%;
  136. background: #fff;
  137. transition: all 0.3s ease-out;
  138. transform: translatex(-100%);
  139. }
  140. </style>