From bfa6690a4d08459ea7397ebd45af88c407046e8a Mon Sep 17 00:00:00 2001
From: xingyy <373639591@qq.com>
Date: Tue, 6 Aug 2024 20:43:08 +0800
Subject: [PATCH] 123
---
package.json | 1 +
pnpm-lock.yaml | 3 +
src/dict/index.js | 2 +-
src/utils/self-adaption.js | 76 +++++-----
src/views/login/index.vue | 11 +-
src/views/login/size375/index.vue | 223 ++++++++++++++----------------
uno.config.js | 1 -
7 files changed, 154 insertions(+), 163 deletions(-)
diff --git a/package.json b/package.json
index a7fcf9e..348ea5d 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"@unocss/reset": "^0.61.9",
"cnjm-postcss-px-to-viewport": "^1.0.1",
"jsdom": "^24.0.0",
+ "lodash": "^4.17.21",
"path": "^0.12.7",
"postcss-preset-env": "^10.0.0",
"postcss-px-to-viewport": "^1.1.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1d4a669..2626dec 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -17,6 +17,9 @@ importers:
jsdom:
specifier: ^24.0.0
version: 24.1.1
+ lodash:
+ specifier: ^4.17.21
+ version: 4.17.21
path:
specifier: ^0.12.7
version: 0.12.7
diff --git a/src/dict/index.js b/src/dict/index.js
index ba966cd..327e88d 100644
--- a/src/dict/index.js
+++ b/src/dict/index.js
@@ -1,3 +1,3 @@
export const sizes = [
- {maxWidth:'375px'}, {maxWidth:'768px'}, {maxWidth:'1440px'}, {maxWidth:'1920px'}
+ {minWidth:'375px',maxWidth:'768px'}, {minWidth:'768px',maxWidth:'1440px'}, {minWidth:'1440px',maxWidth: '1920px'}, {minWidth:'1920px'}
]
diff --git a/src/utils/self-adaption.js b/src/utils/self-adaption.js
index 0c0bb91..f5aa000 100644
--- a/src/utils/self-adaption.js
+++ b/src/utils/self-adaption.js
@@ -1,46 +1,60 @@
-import { ref, onMounted, onBeforeUnmount } from 'vue'
-export function useAdaptation(sizes, handleChange) {
- const mediaQueryLists = sizes.map(size => window.matchMedia(`(max-width: ${size.maxWidth})`));
- const currentDevice = ref(getCurrentDevice())
- function getCurrentDevice() {
+import { ref, onMounted, onBeforeUnmount } from 'vue';
+import debounce from 'lodash/debounce'
+
+export function useAdaptation(ranges, handleChange) {
+ // 创建 media query 对象列表
+ const mediaQueryLists = ranges.map(range => {
+ const minQuery = range.minWidth ? window.matchMedia(`(min-width: ${range.minWidth})`) : null;
+ const maxQuery = range.maxWidth ? window.matchMedia(`(max-width: ${range.maxWidth})`) : null;
+ return { minQuery, maxQuery };
+ });
+
+ // 定义当前匹配的区间
+ const currentRange = ref(getCurrentRange());
+
+ // 获取当前匹配的区间
+ function getCurrentRange() {
for (let i = 0; i < mediaQueryLists.length; i++) {
- if (mediaQueryLists[i].matches) {
- return sizes[i].maxWidth;
+ const { minQuery, maxQuery } = mediaQueryLists[i];
+ const minMatches = minQuery ? minQuery.matches : true;
+ const maxMatches = maxQuery ? maxQuery.matches : true;
+ if (minMatches && maxMatches) {
+ return ranges[i];
}
}
- return sizes[sizes.length - 1].maxWidth
+ return ranges[ranges.length - 1];
}
- const changeHandler = (newValue) => {
- if (typeof handleChange === 'function') {
- handleChange(newValue);
- }
- };
-
- const mediaQueryChangeHandler = () => {
- const newDevice = getCurrentDevice();
- if (currentDevice.value !== newDevice) {
- currentDevice.value = newDevice;
- changeHandler(newDevice);
+ // 处理窗口大小变化(加上防抖)
+ const handleDeviceChange = debounce(() => {
+ const newRange = getCurrentRange();
+ if (currentRange.value !== newRange) {
+ currentRange.value = newRange;
+ if (typeof handleChange === 'function'&&newRange) {
+ handleChange(newRange);
+ }
}
- };
-
- let cleanupHandlers = [];
+ }, 200);
+ // 在组件挂载时添加事件监听器
onMounted(() => {
- mediaQueryLists.forEach(query => {
- query.addEventListener('change', mediaQueryChangeHandler);
- cleanupHandlers.push(() => query.removeEventListener('change', mediaQueryChangeHandler));
+ mediaQueryLists.forEach(({ minQuery, maxQuery }) => {
+ if (minQuery) minQuery.addEventListener('change', handleDeviceChange);
+ if (maxQuery) maxQuery.addEventListener('change', handleDeviceChange);
});
- // Ensure the initial value is correct and trigger the changeHandler with the initial value
- const initialDevice = getCurrentDevice();
- currentDevice.value = initialDevice;
- changeHandler(initialDevice);
+
+ // 初始调用以设置正确的区间
+ handleDeviceChange();
});
+ // 在组件卸载时移除事件监听器
onBeforeUnmount(() => {
- cleanupHandlers.forEach(cleanup => cleanup());
+ mediaQueryLists.forEach(({ minQuery, maxQuery }) => {
+ if (minQuery) minQuery.removeEventListener('change', handleDeviceChange);
+ if (maxQuery) maxQuery.removeEventListener('change', handleDeviceChange);
+ });
});
- return { maxWidth: currentDevice };
+ // 返回当前匹配的区间
+ return { currentRange };
}
diff --git a/src/views/login/index.vue b/src/views/login/index.vue
index 9dd26b5..0f19d67 100644
--- a/src/views/login/index.vue
+++ b/src/views/login/index.vue
@@ -4,13 +4,10 @@ import {sizes} from "@/dict/index.js";
import size375 from '@/views/login/size375/index.vue'
import size768 from '@/views/login/size768/index.vue'
import {computed} from "vue";
-const {maxWidth}= useAdaptation(sizes,(maxWidth)=>{
- console.log('maxWidth',maxWidth.value)
-})
-
+const {currentRange }= useAdaptation([ {minWidth:'0px',maxWidth:'768px'}, {minWidth:'768px',maxWidth:'1440px'}, {minWidth:'1440px',maxWidth: '1920px'}, {minWidth:'1920px'}])
const viewComponent = computed(()=>{
-switch (maxWidth.value){
- case '375px':
+switch (currentRange.value?.minWidth){
+ case '0px':
return size375
case '768px':
return size768
@@ -19,7 +16,7 @@ switch (maxWidth.value){
-
+