Browse Source

优化移动端弹窗展示

Pchen. 3 weeks ago
parent
commit
5627863f58
4 changed files with 100 additions and 9 deletions
  1. 3 0
      src/main.js
  2. 28 0
      src/plugins/responsiveModal.js
  3. 33 7
      src/style.css
  4. 36 2
      src/styles/store-theme.less

+ 3 - 0
src/main.js

@@ -18,6 +18,9 @@ import { router } from './router/'
 import { createPinia } from 'pinia'
 import globalComponents from '@/components'
 import trimInput from '@/plugins/trimInput'
+import { setupResponsiveModal } from '@/plugins/responsiveModal'
+
+setupResponsiveModal()
 
 const app = createApp(App)
 app

+ 28 - 0
src/plugins/responsiveModal.js

@@ -0,0 +1,28 @@
+import { Modal } from '@arco-design/web-vue'
+
+const MOBILE_BREAKPOINT = 768
+const MOBILE_HORIZONTAL_GAP = 24
+const MOBILE_MIN_WIDTH = 280
+
+function getResponsiveModalWidth() {
+  if (typeof window === 'undefined') return undefined
+  if (window.innerWidth > MOBILE_BREAKPOINT) return undefined
+  return Math.max(MOBILE_MIN_WIDTH, window.innerWidth - MOBILE_HORIZONTAL_GAP)
+}
+
+function withResponsiveWidth(options = {}) {
+  const width = getResponsiveModalWidth()
+  if (width === undefined) return options
+  return { ...options, width }
+}
+
+const MODAL_METHODS = ['confirm', 'info', 'success', 'warning', 'error', 'open']
+
+/** 移动端为 Modal 静态方法注入适配宽度,避免 confirm 超出屏幕 */
+export function setupResponsiveModal() {
+  MODAL_METHODS.forEach((method) => {
+    const original = Modal[method]
+    if (typeof original !== 'function') return
+    Modal[method] = (options) => original.call(Modal, withResponsiveWidth(options))
+  })
+}

+ 33 - 7
src/style.css

@@ -84,10 +84,26 @@ h1 {
 }
 
 @media (max-width: 768px) {
-  .arco-modal {
+  .arco-modal-wrapper {
+    box-sizing: border-box;
+    padding: 0 12px;
+    max-width: 100vw;
+  }
+
+  .arco-modal,
+  .arco-modal-simple,
+  .arco-modal-default {
     width: calc(100vw - 24px) !important;
     max-width: calc(100vw - 24px) !important;
+    min-width: 0 !important;
     margin: 12px auto !important;
+    box-sizing: border-box;
+  }
+
+  .arco-modal .arco-modal-title,
+  .arco-modal .arco-modal-body {
+    word-break: break-word;
+    overflow-wrap: anywhere;
   }
 
   .arco-modal .arco-modal-header {
@@ -105,14 +121,24 @@ h1 {
     overflow-y: auto;
   }
 
-  .arco-modal-confirm .arco-modal-footer {
-    display: grid;
-    grid-template-columns: 1fr;
-    gap: 8px;
+  .arco-modal .arco-modal-footer,
+  .arco-modal-confirm .arco-modal-footer,
+  .arco-modal-simple .arco-modal-footer {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: nowrap;
+    align-items: center;
+    justify-content: stretch;
+    gap: 10px;
   }
 
-  .arco-modal-confirm .arco-modal-footer .arco-btn {
-    width: 100%;
+  .arco-modal .arco-modal-footer .arco-btn,
+  .arco-modal-confirm .arco-modal-footer .arco-btn,
+  .arco-modal-simple .arco-modal-footer .arco-btn {
+    flex: 1 1 0;
+    min-width: 0;
+    width: auto !important;
+    margin: 0 !important;
   }
 
   .arco-drawer {

+ 36 - 2
src/styles/store-theme.less

@@ -408,12 +408,28 @@
   }
 }
 
-// —— 弹窗(移动端宽度)——
+// —— 弹窗(移动端宽度,含 Modal.confirm)——
 @media (max-width: @app-breakpoint-md) {
-  .arco-modal {
+  .arco-modal-wrapper {
+    box-sizing: border-box;
+    padding: 0 12px;
+    max-width: 100vw;
+  }
+
+  .arco-modal,
+  .arco-modal-simple,
+  .arco-modal-default {
     width: calc(100vw - 24px) !important;
     max-width: calc(100vw - 24px) !important;
+    min-width: 0 !important;
     margin: 12px auto !important;
+    box-sizing: border-box;
+  }
+
+  .arco-modal .arco-modal-title,
+  .arco-modal .arco-modal-body {
+    word-break: break-word;
+    overflow-wrap: anywhere;
   }
 
   .arco-modal .arco-modal-body {
@@ -431,6 +447,24 @@
     padding-right: 16px;
   }
 
+  .arco-modal .arco-modal-footer,
+  .arco-modal-confirm .arco-modal-footer,
+  .arco-modal-simple .arco-modal-footer {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: nowrap;
+    align-items: center;
+    justify-content: stretch;
+    gap: 10px;
+
+    .arco-btn {
+      flex: 1 1 0;
+      min-width: 0;
+      width: auto !important;
+      margin: 0 !important;
+    }
+  }
+
   .arco-drawer {
     width: 100vw !important;
     max-width: 100vw !important;