index.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <template>
  2. <div
  3. class="volumn-box"
  4. :class="isOpen ? 'active' : ''"
  5. @click="searchMore"
  6. >
  7. <div class="top">
  8. <img
  9. :src="
  10. parseImgUrl('taiguv1/envmonitor/', isOpen ? 'active/curtain.svg' : 'curtain.svg')
  11. "
  12. alt=""
  13. />
  14. </div>
  15. <div class="bottom">
  16. <div class="text">窗帘</div>
  17. <div class="status">{{ controlStatus }}</div>
  18. <div class="control-box">
  19. <div
  20. v-for="item in controlName"
  21. :key="item.value"
  22. >
  23. <div
  24. class="control-item"
  25. :class="item.isActive ? 'active' : ''"
  26. @click.stop="handle(item.value, item.status)"
  27. >{{ item.name }}</div>
  28. </div>
  29. </div>
  30. </div>
  31. </div>
  32. </template>
  33. <script setup>
  34. import { parseImgUrl } from "@/utils";
  35. import { onBeforeUnmount, onMounted, ref } from "vue";
  36. const controlStatus = ref('')
  37. const controlName = ref([
  38. { isActive: false, name: '上', value: 1, status: '开启中' },
  39. { isActive: false, name: '停', value: 2, status: '暂停中' },
  40. { isActive: false, name: '下', value: 0, status: '关闭中' },
  41. ])
  42. const isOpen = ref(true)
  43. const isActive = ref(false)
  44. const emit = defineEmits(['showMore'])
  45. const searchMore = () => {
  46. emit("showMore", 'curtain', true);
  47. }
  48. let timer = null // 添加timer变量
  49. let btnTimer = null;
  50. const handle = (value, status) => {
  51. controlStatus.value = status;
  52. if (btnTimer) {
  53. clearTimeout(btnTimer);
  54. }
  55. controlName.value.forEach(item => {
  56. if (item.value === value) {
  57. item.isActive = true;
  58. btnTimer = setTimeout(() => {
  59. item.isActive = false;
  60. }, 100);
  61. } else {
  62. item.isActive = false;
  63. }
  64. });
  65. if (timer) {
  66. clearTimeout(timer);
  67. }
  68. // 设置新的定时器并保存引用
  69. timer = setTimeout(() => {
  70. controlStatus.value = '';
  71. }, 3000);
  72. }
  73. onBeforeUnmount(() => { });
  74. onMounted(() => { });
  75. </script>
  76. <style lang="scss" scoped>
  77. .volumn-box {
  78. box-sizing: border-box;
  79. display: flex;
  80. flex-direction: column;
  81. justify-content: space-between;
  82. padding: 16px;
  83. width: 100%;
  84. height: 100%;
  85. border-radius: 24px 24px 44px 24px;
  86. background: rgba(255, 255, 255, 0.2);
  87. backdrop-filter: blur(40px);
  88. box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
  89. .top {
  90. display: flex;
  91. justify-content: space-between;
  92. img {
  93. width: 30px;
  94. }
  95. }
  96. .bottom {
  97. // margin-top: 18vh;
  98. // margin-top: 109px;
  99. .text {
  100. //styleName: Chi/Body Large;
  101. font-family: PingFang SC;
  102. font-size: 16px;
  103. font-weight: 300;
  104. line-height: 22px;
  105. letter-spacing: 0.02em;
  106. text-align: left;
  107. text-underline-position: from-font;
  108. text-decoration-skip-ink: none;
  109. color: rgba(255, 255, 255, 1);
  110. padding-bottom: 2px;
  111. }
  112. .status {
  113. //styleName: Chi/Body XS;
  114. height: 15px;
  115. margin-bottom: 10px;
  116. color: var(--Grey, #74808d);
  117. font-family: "PingFang SC";
  118. font-size: 11px;
  119. font-style: normal;
  120. font-weight: 400;
  121. line-height: normal;
  122. letter-spacing: 0.22px;
  123. }
  124. .control-box {
  125. width: 100%;
  126. display: flex;
  127. justify-content: space-between;
  128. .control-item {
  129. display: flex;
  130. align-items: center;
  131. justify-content: center;
  132. width: 36px;
  133. height: 36px;
  134. border-radius: 60px;
  135. opacity: 0.6;
  136. background: var(--White-White-40, rgba(255, 255, 255, 0.4));
  137. backdrop-filter: blur(30px);
  138. font-family: Jost;
  139. font-size: 16px;
  140. color: var(--Blue, #001428);
  141. font-style: normal;
  142. font-weight: 300;
  143. line-height: normal;
  144. }
  145. .control-item.active {
  146. border-radius: 60px;
  147. opacity: 1;
  148. box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
  149. color: #000;
  150. }
  151. }
  152. }
  153. .switch-btn {
  154. width: 50px !important;
  155. height: 28px !important;
  156. border: none;
  157. }
  158. }
  159. .active {
  160. background: rgba(255, 255, 255, 0.8);
  161. backdrop-filter: blur(40px);
  162. box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
  163. .bottom {
  164. .text {
  165. color: rgba(0, 20, 40, 1);
  166. }
  167. .status {
  168. color: rgba(116, 128, 141, 1);
  169. }
  170. }
  171. }
  172. </style>
  173. <style lang="scss">
  174. .volumn-box {
  175. .van-switch__node {
  176. background: rgba(255, 255, 255, 0.6);
  177. width: 24px;
  178. height: 24px;
  179. top: 0.33vh;
  180. }
  181. .van-switch--on.switch-btn {
  182. .van-switch__node {
  183. transform: translate(calc(50px - 28px)) !important;
  184. }
  185. }
  186. .van-switch--on {
  187. background: linear-gradient(
  188. 95.5deg,
  189. #99282b 21.44%,
  190. #a95459 84.95%
  191. ) !important;
  192. .van-switch__node {
  193. background: #fff !important;
  194. }
  195. }
  196. .van-loading__spinner {
  197. color: $elActiveColor !important;
  198. }
  199. .van-switch__loading {
  200. top: 0;
  201. left: 0;
  202. width: 100%;
  203. height: 100%;
  204. line-height: 1;
  205. }
  206. .van-switch--disabled {
  207. opacity: 0.5;
  208. }
  209. }
  210. </style>