index.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. <template>
  2. <div ref="rightPanel" :class="{show:show}" class="rightPanel-container">
  3. <div class="rightPanel-background" />
  4. <div class="rightPanel">
  5. <div class="handle-button" :style="{'top':buttonTop+'px','background-color':theme}" @click="show=!show">
  6. <i :class="show?'el-icon-close':'el-icon-setting'" />
  7. </div>
  8. <div class="rightPanel-items">
  9. <slot />
  10. </div>
  11. </div>
  12. </div>
  13. </template>
  14. <script>
  15. import { addClass, removeClass } from '@/utils'
  16. export default {
  17. name: 'RightPanel',
  18. props: {
  19. clickNotClose: {
  20. default: false,
  21. type: Boolean
  22. },
  23. buttonTop: {
  24. default: 250,
  25. type: Number
  26. }
  27. },
  28. data() {
  29. return {
  30. show: false
  31. }
  32. },
  33. computed: {
  34. theme() {
  35. return this.$store.state.settings.theme
  36. }
  37. },
  38. watch: {
  39. show(value) {
  40. if (value && !this.clickNotClose) {
  41. this.addEventClick()
  42. }
  43. if (value) {
  44. addClass(document.body, 'showRightPanel')
  45. } else {
  46. removeClass(document.body, 'showRightPanel')
  47. }
  48. }
  49. },
  50. mounted() {
  51. this.insertToBody()
  52. },
  53. beforeDestroy() {
  54. const elx = this.$refs.rightPanel
  55. elx.remove()
  56. },
  57. methods: {
  58. addEventClick() {
  59. window.addEventListener('click', this.closeSidebar)
  60. },
  61. closeSidebar(evt) {
  62. const parent = evt.target.closest('.rightPanel')
  63. if (!parent) {
  64. this.show = false
  65. window.removeEventListener('click', this.closeSidebar)
  66. }
  67. },
  68. insertToBody() {
  69. const elx = this.$refs.rightPanel
  70. const body = document.querySelector('body')
  71. body.insertBefore(elx, body.firstChild)
  72. }
  73. }
  74. }
  75. </script>
  76. <style>
  77. .showRightPanel {
  78. overflow: hidden;
  79. position: relative;
  80. width: calc(100% - 15px);
  81. }
  82. </style>
  83. <style lang="scss" scoped>
  84. .rightPanel-background {
  85. position: fixed;
  86. top: 0;
  87. left: 0;
  88. opacity: 0;
  89. transition: opacity .3s cubic-bezier(.7, .3, .1, 1);
  90. background: rgba(0, 0, 0, .2);
  91. z-index: -1;
  92. }
  93. .rightPanel {
  94. width: 100%;
  95. max-width: 260px;
  96. height: 100vh;
  97. position: fixed;
  98. top: 0;
  99. right: 0;
  100. box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05);
  101. transition: all .25s cubic-bezier(.7, .3, .1, 1);
  102. transform: translate(100%);
  103. background: #fff;
  104. z-index: 40000;
  105. }
  106. .show {
  107. transition: all .3s cubic-bezier(.7, .3, .1, 1);
  108. .rightPanel-background {
  109. z-index: 20000;
  110. opacity: 1;
  111. width: 100%;
  112. height: 100%;
  113. }
  114. .rightPanel {
  115. transform: translate(0);
  116. }
  117. }
  118. .handle-button {
  119. width: 48px;
  120. height: 48px;
  121. position: absolute;
  122. left: -48px;
  123. text-align: center;
  124. font-size: 24px;
  125. border-radius: 6px 0 0 6px !important;
  126. z-index: 0;
  127. pointer-events: auto;
  128. cursor: pointer;
  129. color: #fff;
  130. line-height: 48px;
  131. i {
  132. font-size: 24px;
  133. line-height: 48px;
  134. }
  135. }
  136. </style>