vue3+vant創建移動端項目,實戰項目常見採坑記錄

来源:https://www.cnblogs.com/qwrBk/archive/2023/04/17/17325128.html
-Advertisement-
Play Games

前言: 產品背景介紹 我所做的這個項目,剛開始是沒有移動端需求的,等PC端做完了上線使用了幾個月後,突然有一天產品經理找到我說是要做一個在PC端添加一個快速註冊入口,用手機微信掃二位碼進入移動端註冊頁面,用戶註冊。 所以本次需求就是在PC端添加一個tool-tip氣泡型彈出二維碼,再開發一個移動端註 ...


前言:

  產品背景介紹

  我所做的這個項目,剛開始是沒有移動端需求的,等PC端做完了上線使用了幾個月後,突然有一天產品經理找到我說是要做一個在PC端添加一個快速註冊入口,用手機微信掃二位碼進入移動端註冊頁面,用戶註冊。

所以本次需求就是在PC端添加一個tool-tip氣泡型彈出二維碼,再開發一個移動端註冊頁面。

  起初我是在PC項目中引入vant新加了一個模塊來存放移動註冊頁面和註冊成功頁面的,然後想使用postcss-px-to-viewport的exclude和include屬性配置來區分PC和移動頁面,避免樣式干擾。

然而,是我天真了,看網上各種postcss-px-to-viewport的exclude和include的配置,更換各個版本以及相似的更新版本,都不能完美做到相容移動端和PC端,我就放棄了移動pc放在一個項目中了,最終只能單獨的把移動頁面單獨摘出來成立一個單獨項目跑,坑爹啊。

  1. 表單密碼可見切換以及不讓輸入漢字空格

代碼實現:

<van-field               :required="true"               v-model="registerForm.password"               :type="switchPassType ? 'text' : 'password'"               name="password"               label="登錄密碼"               placeholder="請輸入登錄密碼"               :right-icon="switchPassType ? 'eye' : 'closed-eye'"               @click-right-icon="switchPassType = !switchPassType"               :rules="rules.password"               :update:model-value="registerForm.password=registerForm.password.replace(/[\u4e00-\u9fa5/\s+/]/ig,'')"             />   備註:密碼這塊雖然有些網上搜到的讓用vant 自帶的digit屬性讓只能輸入數字,但這個不符合產品需求,密碼應為數字、字母、特殊符號都可輸入。 使用van-field自帶的update:model-value方法進行漢字、空格校驗,親測有效。  

  2. 移動端頁面出現X軸滾動條問題

1) 在index.html文件中添加 <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,viewport-fit=cover"/> 2) 在公共樣式中修改html、body設置的樣式 html {     overflow-y: scroll; }
:root {     overflow-y: auto;     overflow-x: hidden; }
:root body {     position: absolute; }
body {     width: 100%;     margin: 0;     padding: 0;     overflow: hidden; }

  3.使用postcss-px-to-viewport做適配出現的問題

使用教程我就不贅述了,網上一大片,說點有用的 1)相容vant的375設置 在你的vue.config.js文件中添加如下代碼: css: {     loaderOptions: {       postcss: {         postcssOptions: (loaderContext) => {           return {             plugins: [               ["autoprefixer"],               // vant px轉vw。參坑:單獨寫在postcss.config.js中無法解析vant內部樣式               {                 "postcss-px-to-viewport": {                   unitToConvert: "px",                   viewportWidth: loaderContext.resourcePath.includes("vant") ? 375 : 750,                   // viewportWidth: 750,  // 視窗的寬度,對應的是我們設計稿的寬度,一般是750                   // viewportHeight: 1334, // 視窗的高度,根據750設備的寬度來指定,一般指定1334,也可以不配置                   unitPrecision: 6, // 指定`px`轉換為視窗單位值的小數位數                   propList: ["*"],                   viewportUnit: "vw", //指定需要轉換成的視窗單位,建議使用vw                   fontViewportUnit: "vw",                   selectorBlackList: [], // 如['.ignore'], 可以指定不轉換為視窗單位的類,可以自定義,可以無限添加,建議定義一至兩個通用的類名                   minPixelValue: 1, // 小於或等於`1px`不轉換為視窗單位,你也可以設置為你想要的值                   mediaQuery: true, // 允許在媒體查詢中轉換`px`                   exclude: [],                   landscape: false                 },               },             ],           };         },       },     },   } 代碼目錄:

 

備註:其中的exclude屬性不知道樹我本人寫的有問題還是怎麼的,想用它處理views目錄下的特定目錄文件總是不生效,include就更別說了,各種版本、各種寫法都換過了沒啥nuan用。

  4.檢測是否是移動端打開跳轉不同路由

1)路由處理

export const ISMOBILE = function () {

    let flag = navigator.userAgent.match(         /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i     );     return flag; };

  5. DatePicker日期選擇器預設選中當前日期

在這塊有2個坑:

1)它的年份預設最小2013,不能像elementui的日期選擇器一樣自由選擇,所以,使用時你可以使用min-date屬性設置最小年月日。

2)預設選中當前年月日,

currentDate使用計算屬性獲取, 備註:月日不足2位要用0補齊,不然獲取到的當前年月日不對

/**獲取當前日期回填 */ const currentDate = computed(() => {   const nowDate = myDate.toLocaleDateString().split("/");   if (nowDate[1].length < 2) {     nowDate[1] = "0" + nowDate[1];   }   if (nowDate[2].length < 2) {     nowDate[1] = "0" + nowDate[2];   }   return nowDate; });

   6. 表單校驗添加

1)一定要給van-form中添加ref屬性,在van-field中使用name作為校驗標識,使用rules屬性添加校驗規則。

備註:想要對一個欄位進行不同校驗以及不同提示,只能使用多條校驗規則。此處不能像使用elementUi中的callback返回提示語,只能使用message屬性寫死,操蛋啊

   7.文件上傳預覽刪除

直接上代碼,很明瞭:

// 上傳圖片、上傳文件校驗大小和格式 const beforeRead = (file) => {   const correctFormat = ["jpg", "jpeg", "png", "bmp"];   const isArray = Object.prototype.toString.call(file) === "[object Array]";   const isLimit50M = 1024 * 1024 * 6; // 是否大於50M   if (isArray) {     const sizes = file.map((item) => item.size);     if (sizes.some((item) => item > isLimit50M)) {       showNotify({ type: "warning", message: "大小不能超過6M" });       return false;     }     const types = file.map(       ({ name }) => name.slice(name.lastIndexOf(".") + 1) // 尾碼     );     if (!types.every((item) => correctFormat.includes(item))) {       showNotify({ type: "warning", message: "請上傳jpg/jpeg/png/bmp" });       return false;     }   } else {     if (file.size > isLimit50M) {       showNotify({ type: "warning", message: "大小不能超過6M" });       return false;     }     const type = file.name.slice(file.name.lastIndexOf(".") + 1);     if (!correctFormat.includes(type)) {       showNotify({ type: "warning", message: "請上傳jpg/jpeg/png/bmp" });       return false;     }   }   return true; };
// 文件上傳 const fileUpload = (data, key, id, file) => {   fileUploadApi(data)     .then((res) => {       if (res.status === 1) {         res.data.key = new Date().getTime();         res.data.url = res.data.attachPreviewUrl;         res.data.percent = 100;         res.data.status = "success";         res.data.name = res.data.attachSrcName;         res.data.uid = id;         registerForm[key] = [];         registerForm[key].push(res.data);         file.status = "success";         showNotify({ type: "success", message: "上傳成功" });         return true;       } else {         file.status = "failed";         showNotify({ type: "danger", message: "上傳失敗,請重新上傳" });         return false;       }     })     .catch((err) => {       showNotify({ type: "danger", message: err.message });       return false;     }); }; /**文件上傳動作 */ const myBeforeRead = (file, field) => {   if (beforeRead(file)) {     file.status = "uploading";     file.message = "上傳中...";     uploadData.file = file;     uploadData.field = field;     const form = new FormData();     const keys = Object.keys(uploadData);     keys.forEach((key) => {       form.append(key, uploadData[key]);     });     // 後臺介面     if (fileUpload(form, uploadData.field, file.lastModified, file)) {       return true;     } else {       return false;     }   } else {     return false;   } }; /**文件刪除動作 */ const delImg = (file, field) => {   registerForm[field] = [];   proxy.$refs.registerFormRef.validate(field); };

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • TiDB作為NewSQL,其在對MySQL(SQL92協議)的相容上做了很多,MySQL作為當下使用較廣的事務型資料庫,在IT界尤其是互聯網間使用廣泛,那麼對於開發人員來說,1)兩個資料庫產品在SQL開發及調優的過程中,都有哪些差異?在系統遷移前需要提前做哪些準備? 2)TiDB的執行計劃如何查看,... ...
  • GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。 GreatSQL是MySQL的國產分支版本,使用上與MySQL一致。 作者: Yejinrong/葉金榮 文章來源:GreatSQL社區投稿 啟用coredump 製造一個coredump場景 真實故障場景分析跟蹤 上一篇 ...
  • 背景 如今很多網站都引入截圖功能,可用於問題反饋、內容分享等實用需求,而前端截圖也不知不覺成為了首選。今天為大家推薦兩種前端截圖方式,雖然有些局限,但是也能應付大部分項目需求。 Canvas截圖:html2canvas SVG截圖:rasterizehtml 原理 首先來談下兩種前端截圖方式的原理, ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 隔行換色(%): window.onload = function() { var aLi = document.getElementsByTagName('li'); for(var i = 0; i < aLi.length; i++ ...
  • 在 Vue 3 中,watchEffect 是一個用於監聽響應式數據變化的 API。它可以在函數內部自動跟蹤數據的依賴,併在依賴變化時重新運行函數。 watchEffect 的作用以及各個參數的功能講解: watchEffect(effect: (onInvalidate: InvalidateCb ...
  • 入職多年,面對生產環境,儘管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背後,都是寶貴的經驗和教訓,都是項目成員的血淚史。為了更好地防範和遏制今後的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ...
  • 整合 Husky + Lint-staged + Commitlint + Commitizen + cz-git 並配置的 pre-commit 和 commit-msg 兩個鉤子分別實現 Git 提交前代碼檢測和 Git 提交信息規範。 ...
  • 收集一波常見的加速NPM包的CDN,發現有些還是挺好用的,基本上可以替代unpkg、jsdelivr,用來做博客或者網站載入NPM使用還是可以的。 經典老牌的CDN加速 unpkg.com cdn.jsdelivr.net fastly.jsdelivr.net 使用方法:直接進官網,搜NPM包名使 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...