From c170b31f3ab1b07585a6589df4a580468f10ac29 Mon Sep 17 00:00:00 2001 From: yiqiuyang Date: Fri, 31 Jul 2026 11:24:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=87=E4=BB=BD=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/styles/index.scss | 8 + src/components/Banner/index.vue | 3 +- src/components/Swiper/composable.js | 125 ++++++++++++ src/components/Swiper/mobile/index.vue | 183 ++++++++++++++++++ .../{swiper => Swiper/pc}/index.vue | 160 ++------------- src/router/index.js | 20 +- src/router/mobile.js | 20 +- src/views/about/mobile.vue | 6 - src/views/homepage/mobile.vue | 6 - src/views/layout/mobile/index.vue | 2 +- src/views/link/mobile.vue | 6 - src/views/mobile/about/index.vue | 85 ++++++++ src/views/mobile/download/index.vue | 158 +++++++++++++++ src/views/mobile/homepage/index.vue | 176 +++++++++++++++++ src/views/mobile/link/index.vue | 66 +++++++ src/views/mobile/news/detail.vue | 95 +++++++++ src/views/mobile/news/index.vue | 107 ++++++++++ src/views/mobile/product/detail.vue | 175 +++++++++++++++++ src/views/mobile/product/hardwareSystem.vue | 105 ++++++++++ src/views/mobile/product/softwareSystem.vue | 103 ++++++++++ .../mobile.vue => mobile/services/index.vue} | 2 +- src/views/news/mobile.vue | 6 - src/views/news/mobileDetail.vue | 6 - src/views/{ => pc}/about/index.vue | 2 +- src/views/{ => pc}/download/index.vue | 2 +- src/views/pc/homepage/composable.js | 40 ++++ src/views/{ => pc}/homepage/index.vue | 2 +- src/views/{ => pc}/link/index.vue | 2 +- src/views/{ => pc}/link/map.vue | 0 src/views/{ => pc}/news/detail.vue | 0 src/views/{ => pc}/news/index.vue | 2 +- src/views/{ => pc}/news/mock.js | 0 src/views/{ => pc}/product/detail.vue | 0 src/views/{ => pc}/product/hardwareSystem.vue | 2 +- src/views/{ => pc}/product/index.vue | 2 +- src/views/{ => pc}/product/project.vue | 2 +- src/views/{ => pc}/product/softwareSystem.vue | 2 +- src/views/{ => pc}/services/index.vue | 0 src/views/product/mobileDetail.vue | 6 - src/views/product/mobileHardwareSystem.vue | 6 - src/views/product/mobileSoftwareSystem.vue | 6 - src/views/services/mobile.vue | 6 - 42 files changed, 1477 insertions(+), 228 deletions(-) create mode 100644 src/components/Swiper/composable.js create mode 100644 src/components/Swiper/mobile/index.vue rename src/components/{swiper => Swiper/pc}/index.vue (55%) delete mode 100644 src/views/about/mobile.vue delete mode 100644 src/views/homepage/mobile.vue delete mode 100644 src/views/link/mobile.vue create mode 100644 src/views/mobile/about/index.vue create mode 100644 src/views/mobile/download/index.vue create mode 100644 src/views/mobile/homepage/index.vue create mode 100644 src/views/mobile/link/index.vue create mode 100644 src/views/mobile/news/detail.vue create mode 100644 src/views/mobile/news/index.vue create mode 100644 src/views/mobile/product/detail.vue create mode 100644 src/views/mobile/product/hardwareSystem.vue create mode 100644 src/views/mobile/product/softwareSystem.vue rename src/views/{download/mobile.vue => mobile/services/index.vue} (54%) delete mode 100644 src/views/news/mobile.vue delete mode 100644 src/views/news/mobileDetail.vue rename src/views/{ => pc}/about/index.vue (98%) rename src/views/{ => pc}/download/index.vue (99%) create mode 100644 src/views/pc/homepage/composable.js rename src/views/{ => pc}/homepage/index.vue (98%) rename src/views/{ => pc}/link/index.vue (97%) rename src/views/{ => pc}/link/map.vue (100%) rename src/views/{ => pc}/news/detail.vue (100%) rename src/views/{ => pc}/news/index.vue (98%) rename src/views/{ => pc}/news/mock.js (100%) rename src/views/{ => pc}/product/detail.vue (100%) rename src/views/{ => pc}/product/hardwareSystem.vue (97%) rename src/views/{ => pc}/product/index.vue (96%) rename src/views/{ => pc}/product/project.vue (97%) rename src/views/{ => pc}/product/softwareSystem.vue (97%) rename src/views/{ => pc}/services/index.vue (100%) delete mode 100644 src/views/product/mobileDetail.vue delete mode 100644 src/views/product/mobileHardwareSystem.vue delete mode 100644 src/views/product/mobileSoftwareSystem.vue delete mode 100644 src/views/services/mobile.vue diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss index 827f2f7..efed171 100644 --- a/src/assets/styles/index.scss +++ b/src/assets/styles/index.scss @@ -20,6 +20,14 @@ body { height: 600px; margin-bottom: 50px; } + +/* 移动端 Banner 自适应高度 */ +@media screen and (max-width: 999px) { + .banner { + height: auto; + margin-bottom: 20px; + } +} .page { width: 100%; height: 100%; diff --git a/src/components/Banner/index.vue b/src/components/Banner/index.vue index edae95e..a4f53a7 100644 --- a/src/components/Banner/index.vue +++ b/src/components/Banner/index.vue @@ -19,6 +19,7 @@ const props = defineProps({ diff --git a/src/components/Swiper/composable.js b/src/components/Swiper/composable.js new file mode 100644 index 0000000..e231a49 --- /dev/null +++ b/src/components/Swiper/composable.js @@ -0,0 +1,125 @@ +import {ref, computed, watch, nextTick, getCurrentInstance, onUnmounted} from 'vue' + +/** + * Swiper 公用逻辑 composable + * @param {object} props - 组件 props + * @param {object} model - v-model ref (currentPage) + * @param {function} emit - emit 函数 + */ +export function useSwiper(props, model, emit) { + const instance = getCurrentInstance() + const $fontSize = instance.appContext.config.globalProperties.$fontSize + const trackRef = ref(null) + let autoPlayTimer = null + + /* ---------- 计算属性 ---------- */ + const itemWidth = computed(() => $fontSize(props.sourceWidth)) + const itemHeight = computed(() => $fontSize(props.sourceHeight)) + const itemGap = computed(() => $fontSize(props.sourceGap)) + const itemTotalWidth = computed(() => itemWidth.value + itemGap.value) + const viewPortWidth = computed(() => props.pageSize * itemWidth.value + (props.pageSize - 1) * itemGap.value + 'px') + const trackWidth = computed(() => props.data.length * itemTotalWidth.value - itemGap.value + 'px') + const totalPages = computed(() => props.data.length - props.pageSize + 1) + + /* ---------- 方法 ---------- */ + function clickTitle() { + emit('title-click') + } + + function translate(page) { + if (!trackRef.value) return + trackRef.value.style.transition = `transform ${props.transitionDuration}ms ease` + trackRef.value.style.transform = `translateX(-${itemTotalWidth.value * (page - 1)}px)` + } + + function goToPage(page) { + model.value = Number(page) + } + + function nextPage() { + const next = model.value < totalPages.value ? model.value + 1 : 1 + goToPage(next) + } + + function prevPage() { + const prev = model.value > 1 ? model.value - 1 : totalPages.value + goToPage(prev) + } + + function handleItemClick(item, index) { + emit('item-click', item, index) + } + + function handleItemHover(item, index) { + clearInterval(autoPlayTimer) + autoPlayTimer = null + emit('item-hover', item, index) + } + + function handleItemHoverLeave() { + startAutoPlay() + } + + function startAutoPlay() { + if (!props.autoPlay) return + stopAutoPlay() + autoPlayTimer = setInterval(nextPage, 3000) + } + + function stopAutoPlay() { + if (autoPlayTimer) { + clearInterval(autoPlayTimer) + autoPlayTimer = null + } + } + + /* 移动端触摸事件 */ + function handleItemTouchStart(item, index) { + clearInterval(autoPlayTimer) + autoPlayTimer = null + emit('item-hover', item, index) + } + + function handleItemTouchEnd() { + startAutoPlay() + } + + /* ---------- 监听器 ---------- */ + watch(model, (newVal, oldVal) => { + if (newVal !== oldVal) { + nextTick(() => translate(newVal)) + } + }, {immediate: true}) + + watch(() => props.autoPlay, (autoPlay) => { + autoPlay ? startAutoPlay() : stopAutoPlay() + }, {immediate: true}) + + watch(() => props.data.length, (newLen, oldLen) => { + if (newLen !== oldLen && model.value !== 1) { + model.value = 1 + } + }) + + onUnmounted(stopAutoPlay) + + return { + trackRef, + itemWidth, + itemHeight, + itemGap, + itemTotalWidth, + viewPortWidth, + trackWidth, + totalPages, + clickTitle, + goToPage, + nextPage, + prevPage, + handleItemClick, + handleItemHover, + handleItemHoverLeave, + handleItemTouchStart, + handleItemTouchEnd, + } +} diff --git a/src/components/Swiper/mobile/index.vue b/src/components/Swiper/mobile/index.vue new file mode 100644 index 0000000..f0d4638 --- /dev/null +++ b/src/components/Swiper/mobile/index.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/src/components/swiper/index.vue b/src/components/Swiper/pc/index.vue similarity index 55% rename from src/components/swiper/index.vue rename to src/components/Swiper/pc/index.vue index 96e5baf..9fbb1b1 100644 --- a/src/components/swiper/index.vue +++ b/src/components/Swiper/pc/index.vue @@ -1,7 +1,6 @@