资讯详情

资讯详情

vue3-解决uview-plus在分辨率大设备的适配问题

vue3-解决uview-plus在分辨率大设备的适配问题步骤一/main.js...app.use(uviewPlus)// 全局单位改为 rpxuview-plus 数值型尺寸参数如 size11经 addUnit 输出 2×rpx// 随屏宽等比缩放375 基准下视觉不变配合 scripts/uview-px2rpx.mjs 的源码级转换uni.$u.setConfig({config:{unit:rpx}})...步骤二/pages.json...globalStyle:{...rpxCalcMaxDeviceWidth:1920,rpxCalcBaseDeviceWidth:375},...步骤三/scripts/uview-px2rpx.mjs/** * uview-plus px → rpx 批量适配脚本 * * 背景uview-plus 组件样式大量使用 px按 375 设计稿在大分辨率853下不会随屏宽缩放 * 而 uni-app 的 rpx 会编译为 rem 并随屏宽等比缩放。 * * 转换规则375 视觉零变化 * CSS: 44px - 88rpx 1px 发丝线保留不转 * JS 默认值: 44px - 88rpx仅转换“纯单位字符串字面量”如 props 默认值 * * 处理范围uni_modules/uview-plus * 1. *.vue —— 仅 style 块内部script / 模板一律不动 * 2. *.scss —— 全部含 components 下的 vue.scss、nvue.scss、theme-vars.scss * 3. components 下所有 .js —— 仅 Xpx 形式的字符串字面量props 默认值 * 4. INLINE_VUE_DIRS 白名单内组件的 .vue —— 模板/脚本中的 Xpx 字符串字面量 * * 排除含运行时计算的 px 或 canvas 绘制业务未使用 * u-parse / u-upload / u-markdown、*.wxs、libs 下所有 js、*backup* 文件 * * 用法项目根目录执行 * node scripts/uview-px2rpx.mjs # 实际写入 * node scripts/uview-px2rpx.mjs --dry # 仅预览统计 * * 说明脚本幂等转换后的 rpx 不会被再次匹配可放心重复执行。 * * 升级 uview-plus 后的完整流程 * 1. 升级前备份整个 uni_modules/uview-plus 目录团队有自定义组件和 addUnit 改动升级会整体覆盖 * 2. HBuilderX 插件市场升级 uview-plus * 3. 从备份恢复团队的修改重点两处 * a. libs/function/index.js 的 addUnit —— 必须保留 unitrpx 时 value*2 的逻辑 * 这是全局单位方案的核心没有它数值型 props 会在 375 下减半 * b. 团队自定义组件目录u-box / u-card 等非官方组件升级会被删掉 * 4. 项目根目录执行node scripts/uview-px2rpx.mjs可先 --dry 预览 * 样式块 / scss / JS 默认值 / 白名单组件内联字符串会自动恢复转换 * 5. 手工补 3 处脚本覆盖不到的修复升级会还原它们 * a. u-button.vue3 处 textSize px 拼接 → addUnit(textSize) / addUnit(this.textSize) * 并在 import 与 methods 中加入 addUnit * b. u-search.vue 模板customStyleline-height: 12px → 24rpx * c. u-input.vue 模板customStyleline-height: 12px → 24rpx * 6. main.js 的 setConfig / pages.json 的 rpxCalcMaxDeviceWidth / main.scss * 均在项目目录下不受插件升级影响无需重做 */import{readFileSync,writeFileSync,readdirSync,statSync}fromnode:fsimport{join,relative,dirname,resolve}fromnode:pathimport{fileURLToPath}fromnode:urlconst__dirnamedirname(fileURLToPath(import.meta.url))constUV_DIRresolve(__dirname,../uni_modules/uview-plus)constDRYprocess.argv.includes(--dry)// 排除的组件目录运行时计算 px / canvas 绘制 / 业务未使用constEXCLUDE_DIRS[u-parse,u-upload,u-markdown]// 第二批业务在用组件的“模板/脚本内联 px 字符串”Xpx 字面量均为尺寸类样式值// 经组件内 addUnit/getPx 消费转 rpx 后运行时均可正确换算// 注意往此列表加组件前需人工确认其 script 中没有把 Xpx 字符串用于 canvas 绘制或// 测量比较等非样式用途canvas 类组件如 u-poster/u-signature/u-qrcode 请勿加入constINLINE_VUE_DIRS[u-action-sheet,u-alert,u-back-top,u-button,u-calendar,u-card,u-checkbox,u-code-input,u-form-item,u-image,u-index-list,u-input,u-modal,u-pull-refresh,u-radio,u-search,u-select,u-skeleton,u-slider,u-steps-item,u-swipe-action-item,u-tag,u-textarea,u-toast]constwalk(dir,out[]){for(constnameofreaddirSync(dir)){constfulljoin(dir,name)constststatSync(full)if(st.isDirectory()){if(EXCLUDE_DIRS.includes(name))continuewalk(full,out)}else{out.push(full)}}returnout}// CSS 上下文的 px不匹配 rpx/upx/px2 等1px 发丝线保留constPX_RE/(-?\d*\.?\d)px\b/g// JS 中“纯单位字符串字面量”44px / 44pxconstJS_STR_RE/([])(-?\d*\.?\d)px\1/gconstconvertValue(num){constvparseFloat(num)if(v1||v-1)returnnull// 发丝线保留returnString(parseFloat((v*2).toFixed(4)))rpx}// 跳过注释行// * /*避免改到注释里的示例代码constisCommentLine(line)/^\s*(\/\/|\*|\/\*)/.test(line)// CSS 文本转换屏蔽 url(...) 内的字体/图片地址避免误伤跳过注释行constconvertCss(text){constmasked[]letmaskedTexttext.replace(/url\([^)]*\)/g,(m){masked.push(m)return__UVIEW_URL_MASK_${masked.length-1}__})letcount0constlinesmaskedText.split(\n).map((line){if(isCommentLine(line)||!PX_RE.test(line))returnlinePX_RE.lastIndex0returnline.replace(PX_RE,(m,num){constrconvertValue(num)if(rnull)returnm countreturnr})})letoutlines.join(\n)outout.replace(/__UVIEW_URL_MASK_(\d)__/g,(_,i)masked[i])return{text:out,count}}// JS 文本转换仅字符串字面量跳过注释行constconvertJs(text){letcount0constlinestext.split(\n).map((line){if(isCommentLine(line)||!JS_STR_RE.test(line))returnlineJS_STR_RE.lastIndex0returnline.replace(JS_STR_RE,(m,quote,num){constrconvertValue(num)if(rnull)returnm countreturn${quote}${r}${quote}})})return{text:lines.join(\n),count}}// .vue仅 style 块内部constconvertVue(text){letcount0constouttext.replace(/(style\b[^]*)([\s\S]*?)(\/style)/g,(m,open,css,close){constrconvertCss(css)countr.countreturnopenr.textclose})return{text:out,count}}constfileswalk(UV_DIR)constresults[]for(constfileoffiles){constrelrelative(UV_DIR,file).replace(/\\/g,/)if(/backup/i.test(rel))continueconstextfile.slice(file.lastIndexOf(.)).toLowerCase()constisComponentsJsrel.startsWith(components/)ext.jsconstisScssext.scssconstisVueext.vueif(!isComponentsJs!isScss!isVue)continueif(isComponentsJs/\.wxs$|\.sjs$/.test(file))continueconstsrcreadFileSync(file,utf8)lettextsrcletcount0if(isVue){constrconvertVue(text)textr.text countr.count// 第二批在用组件的模板/脚本内联 Xpx 字符串constcompDirrel.split(/)[1]if(INLINE_VUE_DIRS.includes(compDir)){constr2convertJs(text)textr2.text countr2.count}}elseif(isScss){constrconvertCss(text)textr.text countr.count}else{constrconvertJs(text)textr.text countr.count}if(count0){results.push({rel,count})if(!DRY)writeFileSync(file,text,utf8)}}results.sort((a,b)b.count-a.count)for(constrofresults)console.log(String(r.count).padStart(4),r.rel)console.log(\n${DRY?[DRY] :}共${results.length}个文件替换${results.reduce((s,r)sr.count,0)}处 px - 2x rpx)console.log(排除目录: EXCLUDE_DIRS.join(, )u-parse/u-upload/u-markdown含运行时计算 px业务未使用)步骤四用法项目根目录执行​ node scripts/uview-px2rpx.mjs --dry # 仅预览统计​ node scripts/uview-px2rpx.mjs # 实际写入​ 说明脚本幂等转换后的 rpx 不会被再次匹配可放心重复执行。/** * uview-plus px → rpx 批量适配脚本 * * 背景uview-plus 组件样式大量使用 px按 375 设计稿在大分辨率853下不会随屏宽缩放 * 而 uni-app 的 rpx 会编译为 rem 并随屏宽等比缩放。 * * 转换规则375 视觉零变化 * CSS: 44px - 88rpx 1px 发丝线保留不转 * JS 默认值: 44px - 88rpx仅转换“纯单位字符串字面量”如 props 默认值 * * 处理范围uni_modules/uview-plus * 1. *.vue —— 仅 style 块内部script / 模板一律不动 * 2. *.scss —— 全部含 components 下的 vue.scss、nvue.scss、theme-vars.scss * 3. components 下所有 .js —— 仅 Xpx 形式的字符串字面量props 默认值 * 4. INLINE_VUE_DIRS 白名单内组件的 .vue —— 模板/脚本中的 Xpx 字符串字面量 * * 排除含运行时计算的 px 或 canvas 绘制业务未使用 * u-parse / u-upload / u-markdown、*.wxs、libs 下所有 js、*backup* 文件 * * 用法项目根目录执行 * node scripts/uview-px2rpx.mjs # 实际写入 * node scripts/uview-px2rpx.mjs --dry # 仅预览统计 * * 说明脚本幂等转换后的 rpx 不会被再次匹配可放心重复执行。 * * 升级 uview-plus 后的完整流程 * 1. 升级前备份整个 uni_modules/uview-plus 目录团队有自定义组件和 addUnit 改动升级会整体覆盖 * 2. HBuilderX 插件市场升级 uview-plus * 3. 从备份恢复团队的修改重点两处 * a. libs/function/index.js 的 addUnit —— 必须保留 unitrpx 时 value*2 的逻辑 * 这是全局单位方案的核心没有它数值型 props 会在 375 下减半 * b. 团队自定义组件目录u-box / u-card 等非官方组件升级会被删掉 * 4. 项目根目录执行node scripts/uview-px2rpx.mjs可先 --dry 预览 * 样式块 / scss / JS 默认值 / 白名单组件内联字符串会自动恢复转换 * 5. 手工补 3 处脚本覆盖不到的修复升级会还原它们 * a. u-button.vue3 处 textSize px 拼接 → addUnit(textSize) / addUnit(this.textSize) * 并在 import 与 methods 中加入 addUnit * b. u-search.vue 模板customStyleline-height: 12px → 24rpx * c. u-input.vue 模板customStyleline-height: 12px → 24rpx * 6. main.js 的 setConfig / pages.json 的 rpxCalcMaxDeviceWidth / main.scss * 均在项目目录下不受插件升级影响无需重做 */
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →