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