uni-drawer.vue 2.6 KB

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