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){