HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

UniApp 原生插件集合(2026)

前言

本文整理了一些比较常用的原生插件,包括扫码、图片选择、文件选择、图片编辑、应用通知、应用未读角标、开机自启、sqlite数据库、保活、快捷方式、图片水印、视频压缩、动态修改应用图标等等,有其他需要可以留言,感谢支持。


📑 目录

第一列 第二列 第三列
1. 扫码(6款) 14. 地图 27. 监听系统广播、自定义广播
2. 文件选择 15. 悬浮窗 28. 监听通知栏消息(支持白黑名单、过滤)
3. 图片选择 16. 画中画 29. 全局置灰、哀悼置灰(可动态、同时支持nvue、vue)
4. 图片编辑 17. 获取设备唯一标识 30. 窗口小工具、桌面小部件、微件
5. 图片压缩 18. WebSocket原生服务(后台) 31. 用其他应用打开、分享
6. 图片水印 19. 安卓快捷方式(桌面长按app图标) 32. 来电显示
7. 视频压缩、剪辑 20. 动态切换应用图标、名称 33. 抖音授权登录、发布、分享
8. 应用消息通知 21. 动态修改状态栏、导航栏 34. 反射方法调用插件
9. 应用未读角标 22. 原生Toast弹窗提示(穿透所有界面) 35. 字母索引列表插件(组件版)
10. 保活 23. PDF阅读 36. 权限申请插件(权限使用说明)
11. 开机自启 24. 声音提示、震动提示、语音播报 37. 桌面应用插件
12. 数据库 25. 短信监听(验证码)
13. 定位 26. 智能安装(自动升级)

⭐ 如果这些插件对您有帮助,欢迎点赞、收藏、分享!⭐

感谢支持!

继续阅读 »

前言

本文整理了一些比较常用的原生插件,包括扫码、图片选择、文件选择、图片编辑、应用通知、应用未读角标、开机自启、sqlite数据库、保活、快捷方式、图片水印、视频压缩、动态修改应用图标等等,有其他需要可以留言,感谢支持。


📑 目录

第一列 第二列 第三列
1. 扫码(6款) 14. 地图 27. 监听系统广播、自定义广播
2. 文件选择 15. 悬浮窗 28. 监听通知栏消息(支持白黑名单、过滤)
3. 图片选择 16. 画中画 29. 全局置灰、哀悼置灰(可动态、同时支持nvue、vue)
4. 图片编辑 17. 获取设备唯一标识 30. 窗口小工具、桌面小部件、微件
5. 图片压缩 18. WebSocket原生服务(后台) 31. 用其他应用打开、分享
6. 图片水印 19. 安卓快捷方式(桌面长按app图标) 32. 来电显示
7. 视频压缩、剪辑 20. 动态切换应用图标、名称 33. 抖音授权登录、发布、分享
8. 应用消息通知 21. 动态修改状态栏、导航栏 34. 反射方法调用插件
9. 应用未读角标 22. 原生Toast弹窗提示(穿透所有界面) 35. 字母索引列表插件(组件版)
10. 保活 23. PDF阅读 36. 权限申请插件(权限使用说明)
11. 开机自启 24. 声音提示、震动提示、语音播报 37. 桌面应用插件
12. 数据库 25. 短信监听(验证码)
13. 定位 26. 智能安装(自动升级)

⭐ 如果这些插件对您有帮助,欢迎点赞、收藏、分享!⭐

感谢支持!

收起阅读 »

小程序端解决分包的uni_modules打包后产物进入主包中的问题

体积优化 微信小程序 uni-app-x uni-app

配置

分包优化

需要在 mainfest.json 指定小程序节点下添加如下配置,例如:

{  
  "mp-weixin": {  
         "optimization": {  
            "subPackages": true  
          },  
        "usingComponents": true  
  }  
}

主包分包的 uni_modules

首先,主包的 uni_moudles 要放在主包的根目录下,分包的 uni_moudles 要放在分包的根目录下,参考附件的第一个图片。

然后,在 pages.json 中配置组件 easycom 引入规则,这一步是为了避免同一个组件库被主包分包都使用,出现识别错误的问题,例如,我在 uniappx 项目中使用了 rice-ui 组件库,可以这样配置

{  
  "easycom": {  
        "autoscan": true,  
        "custom": {  
            "^rice-(.*)": "uni_modules/rice-ui/components/rice-$1/rice-$1.uvue",  
            "^sub-rice-(.*)": "sub/uni_modules/rice-ui/components/rice-$1/rice-$1.uvue"  
        }  
    }  
}

这样,分包用组件就写 sub-rice-avatar,主包就是 rice-button

效果参考附件的第二张图片

示例项目

参考附件三

继续阅读 »

配置

分包优化

需要在 mainfest.json 指定小程序节点下添加如下配置,例如:

{  
  "mp-weixin": {  
         "optimization": {  
            "subPackages": true  
          },  
        "usingComponents": true  
  }  
}

主包分包的 uni_modules

首先,主包的 uni_moudles 要放在主包的根目录下,分包的 uni_moudles 要放在分包的根目录下,参考附件的第一个图片。

然后,在 pages.json 中配置组件 easycom 引入规则,这一步是为了避免同一个组件库被主包分包都使用,出现识别错误的问题,例如,我在 uniappx 项目中使用了 rice-ui 组件库,可以这样配置

{  
  "easycom": {  
        "autoscan": true,  
        "custom": {  
            "^rice-(.*)": "uni_modules/rice-ui/components/rice-$1/rice-$1.uvue",  
            "^sub-rice-(.*)": "sub/uni_modules/rice-ui/components/rice-$1/rice-$1.uvue"  
        }  
    }  
}

这样,分包用组件就写 sub-rice-avatar,主包就是 rice-button

效果参考附件的第二张图片

示例项目

参考附件三

收起阅读 »

删帖

苹果内购 应用内支付

帖子不删掉改空帖

帖子不删掉改空帖

uni-app仿deepseek跨三端流式ai实例|uniapp聊天ai

sse OpenAI vue3 uni_ai uni_app

经过一个多月迭代升级,2026最新款uniapp+vue3+deepseek搭建小程序.安卓.H5端流式打字ai对话模板。支持深度思考、复制代码、latex数学公式、链接、图片预览等功能。

三端效果如下:

运用技术:

  • 编辑器:HbuilderX 4.87
  • 技术框架:uni-app+vue3+pinia2+vite5
  • 大模型框架:DeepSeek-V3.2
  • 组件库:uni-ui+uv-ui
  • 高亮插件:highlight.js
  • markdown渲染:ua-markdown+mp-html
  • 本地缓存:pinia-plugin-unistorage

项目结构目录

> #### uniapp-deepseek跨三端流式ai模板已经同步到我的原创作品集。
> 2026版uniapp+deepseek+vue3跨端AI流式输出对话模板

新增支持小程序端复制代码、latex数学公式、表格、链接复制、预览图片等功能。

h5端支持mermaid图表渲染,支持运行到pc端以750px宽度显示页面。

作者:xiaoyan2017
链接: https://www.cnblogs.com/xiaoyan2017/p/19599014
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

继续阅读 »

经过一个多月迭代升级,2026最新款uniapp+vue3+deepseek搭建小程序.安卓.H5端流式打字ai对话模板。支持深度思考、复制代码、latex数学公式、链接、图片预览等功能。

三端效果如下:

运用技术:

  • 编辑器:HbuilderX 4.87
  • 技术框架:uni-app+vue3+pinia2+vite5
  • 大模型框架:DeepSeek-V3.2
  • 组件库:uni-ui+uv-ui
  • 高亮插件:highlight.js
  • markdown渲染:ua-markdown+mp-html
  • 本地缓存:pinia-plugin-unistorage

项目结构目录

> #### uniapp-deepseek跨三端流式ai模板已经同步到我的原创作品集。
> 2026版uniapp+deepseek+vue3跨端AI流式输出对话模板

新增支持小程序端复制代码、latex数学公式、表格、链接复制、预览图片等功能。

h5端支持mermaid图表渲染,支持运行到pc端以750px宽度显示页面。

作者:xiaoyan2017
链接: https://www.cnblogs.com/xiaoyan2017/p/19599014
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

收起阅读 »

uniapp_rfid

UHFA100_SDK_Android,联系微信:idraksoft01

UHFA100_SDK_Android,联系微信:idraksoft01

uni-app x 鸿蒙版蒸汽模式,渲染速度超过原生;uni-agent上线,AI真的能替你写代码了

公告

uni-app x的蒸汽模式,率先在鸿蒙平台发布

uni-app x成为鸿蒙平台应用开发最高性能的原生开发方案,不止超过了其他框架,也超过了原生数倍。详见

uni-app x的iOS和Android平台,也很快会推出蒸汽模式,提供超过iOS/Android原生开发的性能。敬请期待。

uni-agent,顶尖模型和为uni深度优化的agent

uni-agent不是AI辅助编程,而是AI替你编程。你只需要给它发送要求、以及验收它的成果。详见

DCloud云打包计费规则调整公告

详见:https://ask.dcloud.net.cn/article/42315

继续阅读 »

uni-app x的蒸汽模式,率先在鸿蒙平台发布

uni-app x成为鸿蒙平台应用开发最高性能的原生开发方案,不止超过了其他框架,也超过了原生数倍。详见

uni-app x的iOS和Android平台,也很快会推出蒸汽模式,提供超过iOS/Android原生开发的性能。敬请期待。

uni-agent,顶尖模型和为uni深度优化的agent

uni-agent不是AI辅助编程,而是AI替你编程。你只需要给它发送要求、以及验收它的成果。详见

DCloud云打包计费规则调整公告

详见:https://ask.dcloud.net.cn/article/42315

收起阅读 »

UniApp 原生插件集合(2026)

分享插件

前言

本文整理了一些比较常用的原生插件,包括扫码、图片选择、文件选择、图片编辑、应用通知、应用未读角标、开机自启、sqlite数据库、保活、快捷方式、图片水印、视频压缩、动态修改应用图标等等,有其他需要可以留言,感谢支持。


📑 目录

作者博客 市场主页 社区主页
1. 扫码(6款) 14. 地图 27. 监听系统广播、自定义广播
2. 文件选择 15. 悬浮窗 28. 监听通知栏消息(支持白黑名单、过滤)
3. 图片选择 16. 画中画 29. 全局置灰、哀悼置灰(可动态、同时支持nvue、vue)
4. 图片编辑 17. 获取设备唯一标识 30. 窗口小工具、桌面小部件、微件
5. 图片压缩 18. WebSocket原生服务(后台) 31. 用其他应用打开、分享
6. 图片水印 19. 安卓快捷方式(桌面长按app图标) 32. 来电显示
7. 视频压缩、剪辑 20. 动态切换应用图标、名称 33. 抖音授权登录、发布、分享
8. 应用消息通知 21. 动态修改状态栏、导航栏 34. 反射方法调用插件
9. 应用未读角标 22. 原生Toast弹窗提示(穿透所有界面) 35. 字母索引列表插件(组件版)
10. 保活 23. PDF阅读 36. 权限申请插件(权限使用说明)
11. 开机自启 24. 声音提示、震动提示、语音播报 37. 桌面应用插件
12. 数据库 25. 短信监听(验证码)
13. 定位 26. 智能安装(自动升级)

👤 作者介绍

作者: 三杯五岳(q:2579546054)

专注于 UniApp 原生插件、UTS插件开发,包括安卓、苹果、鸿蒙,致力于为开发者提供高质量、易用的原生插件解决方案。

主要方向:

  • UniApp 原生插件开发
  • UniApp UTS插件开发
  • Android、iOS、Harmony原生项目开发
  • 移动端跨平台项目开发
  • 微信小程序
  • PC前端

> 💡 提示: 如需定制开发、技术支持或有其他需求,欢迎通过QQ或留言咨询!


⭐ 如果这些插件对您有帮助,欢迎点赞、收藏、分享!⭐

感谢支持!

继续阅读 »

前言

本文整理了一些比较常用的原生插件,包括扫码、图片选择、文件选择、图片编辑、应用通知、应用未读角标、开机自启、sqlite数据库、保活、快捷方式、图片水印、视频压缩、动态修改应用图标等等,有其他需要可以留言,感谢支持。


📑 目录

作者博客 市场主页 社区主页
1. 扫码(6款) 14. 地图 27. 监听系统广播、自定义广播
2. 文件选择 15. 悬浮窗 28. 监听通知栏消息(支持白黑名单、过滤)
3. 图片选择 16. 画中画 29. 全局置灰、哀悼置灰(可动态、同时支持nvue、vue)
4. 图片编辑 17. 获取设备唯一标识 30. 窗口小工具、桌面小部件、微件
5. 图片压缩 18. WebSocket原生服务(后台) 31. 用其他应用打开、分享
6. 图片水印 19. 安卓快捷方式(桌面长按app图标) 32. 来电显示
7. 视频压缩、剪辑 20. 动态切换应用图标、名称 33. 抖音授权登录、发布、分享
8. 应用消息通知 21. 动态修改状态栏、导航栏 34. 反射方法调用插件
9. 应用未读角标 22. 原生Toast弹窗提示(穿透所有界面) 35. 字母索引列表插件(组件版)
10. 保活 23. PDF阅读 36. 权限申请插件(权限使用说明)
11. 开机自启 24. 声音提示、震动提示、语音播报 37. 桌面应用插件
12. 数据库 25. 短信监听(验证码)
13. 定位 26. 智能安装(自动升级)

👤 作者介绍

作者: 三杯五岳(q:2579546054)

专注于 UniApp 原生插件、UTS插件开发,包括安卓、苹果、鸿蒙,致力于为开发者提供高质量、易用的原生插件解决方案。

主要方向:

  • UniApp 原生插件开发
  • UniApp UTS插件开发
  • Android、iOS、Harmony原生项目开发
  • 移动端跨平台项目开发
  • 微信小程序
  • PC前端

> 💡 提示: 如需定制开发、技术支持或有其他需求,欢迎通过QQ或留言咨询!


⭐ 如果这些插件对您有帮助,欢迎点赞、收藏、分享!⭐

感谢支持!

收起阅读 »

关于uni-app X项目离线打包基座不显示静态资源的解决方法

离线打包 安卓

场景:在AndroidStudio中运行uniapp-x SDK,移除uniapp调试信息,移除uniapp调试aar,静态资源不显示。打算打包release版本前测试一下的,即使打包release版本还是不显示静态资源。
解决方法:
1、在AndroidManifest.xml中关闭调试
即删除 <meta-data android:name="DCLOUD_DEBUG" android:value="true"/>
// 这里我把值改为false也没用,所有直接删除了保险一些
2、修改uniappx模块的build.gradle强制指定assets位置

    sourceSets {  
        main {  
            assets {  
                srcDirs = [  
                        'src/main/assets',    
                ]  
                include '** / *'   
            }  
        }  
    }  
继续阅读 »

场景:在AndroidStudio中运行uniapp-x SDK,移除uniapp调试信息,移除uniapp调试aar,静态资源不显示。打算打包release版本前测试一下的,即使打包release版本还是不显示静态资源。
解决方法:
1、在AndroidManifest.xml中关闭调试
即删除 <meta-data android:name="DCLOUD_DEBUG" android:value="true"/>
// 这里我把值改为false也没用,所有直接删除了保险一些
2、修改uniappx模块的build.gradle强制指定assets位置

    sourceSets {  
        main {  
            assets {  
                srcDirs = [  
                        'src/main/assets',    
                ]  
                include '** / *'   
            }  
        }  
    }  
收起阅读 »

安卓启动图变形问题解决方案,.9.png启动图生成

.9.png

使用Android Studio工具去生成,效果嘎嘎好

有不会的联系我,或者发送邮件:it2003wei@163.com,请我喝杯奶茶帮你搞定嘻嘻

使用Android Studio工具去生成,效果嘎嘎好

有不会的联系我,或者发送邮件:it2003wei@163.com,请我喝杯奶茶帮你搞定嘻嘻

找个前端高手

外包

有个小项目外包前端,需要适配安卓+苹果+鸿蒙,有空闲的来。需要有至少两个以上APP开发经历,vue3+ts。

有个小项目外包前端,需要适配安卓+苹果+鸿蒙,有空闲的来。需要有至少两个以上APP开发经历,vue3+ts。

h5端尺寸转换逻辑

uni_app项目 h5

vue3 + vite

vue3 下 , h5使用rpx 时, 会 编译成 rem

注册 postcss 的 plugin

在/node_modules/@dcloudio/uni-h5-vite/dist/plugin/config.js,
代码是, 用的 是config 这个钩子

 css: {  
    postcss: {  
        plugins: (0, uni_cli_shared_1.initPostcssPlugin)({  
            uniApp: (0, uni_cli_shared_1.parseRpx2UnitOnce)(inputDir, process.env.UNI_PLATFORM),  
        }),  
    },  
},

parseRpx2UnitOnce , 选定使用的单位

exports.parseRpx2UnitOnce = (0, uni_shared_1.once)((inputDir, platform = 'h5') => {  
    // 如果是  h5/app/鸿蒙 会使用 defaultRpx2Unit  
    const rpx2unit = platform === 'h5' || platform === 'app' || platform === 'app-harmony'  
        ? uni_shared_1.defaultRpx2Unit  
        : uni_shared_1.defaultMiniProgramRpx2Unit;  
    const manifestJson = (0, exports.parseManifestJsonOnce)(inputDir);  
    let platformOptions = getPlatformManifestJson(manifestJson, platform);  
    if (platformOptions && platformOptions.rpx) {  
        return (0, shared_1.extend)({}, rpx2unit, platformOptions);  
    }  
    return (0, shared_1.extend)({}, rpx2unit);  
});

都有啥呢 ?

const defaultRpx2Unit = {  
    unit: 'rem',  
    unitRatio: 10 / 320,  
    unitPrecision: 5,  
};  
const defaultMiniProgramRpx2Unit = {  
    unit: 'rpx',  
    unitRatio: 1,  
    unitPrecision: 1,  
};

但是 注意这里 let platformOptions = getPlatformManifestJson(manifestJson, platform);
还是 会从 mainfest中 获取 配置的, 如果有 , 就用 mainfest 中的,
也就是 你可以 在 manifest.json的 h5节点下 , 覆盖 一些 配置 , 例如

    "h5": {  
        "router": {  
            "mode": "history"  
        },  
        "unit": "px",  
        "unitRatio": 0.5,  
        "unitPrecision": 2,  
    }

但是 文档里 , 我没有 找到

哪里 修改的 rpx 2 rem 呢?

在这里 /node_modules/@dcloudio/uni-cli-shared/dist/postcss/plugins/uniapp.js

const uniapp = (opts) => {  
    const platform = process.env.UNI_PLATFORM;  
    const { unit, unitRatio, unitPrecision } = (0, shared_1.extend)({}, defaultUniAppCssProcessorOptions, opts);  
    const rpx2unit = (0, uni_shared_1.createRpx2Unit)(unit, unitRatio, unitPrecision);  
    return {  
        postcssPlugin: 'uni-app',  
        prepare() {  
            return {  
                OnceExit(root) {  
                    root.walkDecls(walkDecls(rpx2unit));  
                    const rewriteTag = transforms[platform];  
                    filterPrefersColorScheme(root);  
                    if (rewriteTag) {  
                        root.walkRules(walkRules({  
                            rewriteTag,  
                        }));  
                    }  
                },  
            };  
        },  
    };  
};

就是 遍历 然后 替换

function walkDecls(rpx2unit) {  
    return (decl) => {  
        const { value } = decl;  
        if (value.indexOf('rpx') === -1 && value.indexOf('upx') === -1) {  
            return;  
        }  
        // 如果有 rpx 或者upx, 就调用rpx2unit  
        decl.value = rpx2unit(decl.value);  
    };  
}
const unitRE = new RegExp(`"[^"]+"|'[^']+'|url\\([^)]+\\)|(\\d*\\.?\\d+)[r|u]px`, 'g');  

// 这里的  参数 就是  defaultRpx2Unit的三个参数  
function createRpx2Unit(unit, unitRatio, unitPrecision) {  
    // ignore: rpxCalcIncludeWidth  
    return (val) => val.replace(unitRE, (m, $1) => {  
        if (!$1) {  
            return m;  
        }  
        if (unitRatio === 1) {  
            return `${$1}${unit}`;  
        }  
        // 替换 为 rem  
        // 就是  * unitRatio, 然后 保留unitPrecision 位的小数  
        const value = toFixed(parseFloat($1) * unitRatio, unitPrecision);  
        return value === 0 ? '0' : `${value}${unit}`;  
    });  
}

我是 分割线----------------------------------------------------------------------------------------------------------------------------------------------------------------

vue2 + webpack

再 说一下 vue2的 处理, vue2 是 依托于 vue-cli-service

查看打包结果

写一个 最简单的 项目,
查看 打包后的 结果

 ___CSS_LOADER_EXPORT___.push([  
            module.id,  
            '@charset "UTF-8";\n/**\n  */.ggdxd[data-v-4551d3b2]{height:%?600?%;background-color:pink}',  
            "",  
        ]);

是 内联css ,
而 可以 修改么? 可以 在 vue.config.js中 设置css.extract么?

不可以

查看代码, uni 是 使用 自定义 的 vue-cli-service 插件,
/node_modules/@dcloudio/vue-cli-plugin-uni/index.js

h5 强制要 内联css...

if (process.env.UNI_PLATFORM === 'h5' || process.env.UNI_USING_V3) {  
    options.css.extract = false  
} else {  
    options.css.extract = true  
}

height:%?600?%

在 cli 项目中, 根目录下会有postcss.config.js
实际上 使用了 uni的 一个自定义 插件require('@dcloudio/vue-cli-plugin-uni/packages/postcss')
在 parseWord方法中

if (process.env.UNI_PLATFORM === 'h5') {  
    if (u === 'upx' || u === 'rpx') {  
          // 这里 变成了很奇怪的东西  
      node.value = `%?${num}?%`  
    }  
}

也就是 在编译的产物中, rpx/upx 都转成了 %?${num}?%的 格式

啥时候 转成 px 哦?

是 运行时!

运行时的 转换代码 是哪里来的?

是 通过 webpack的 loader 处理的

我写了一个 webpack 插件, 获取了 resolve 之后的 样式使用的loader

[  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/pitcher.js",  

  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/h5-vue-style-loader/index.js",  

  "/node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader/index.js",  
  "/node_modules/postcss-loader/dist/cjs.js",  
  "/node_modules/postcss-loader/dist/cjs.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/sass-loader/dist/cjs.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader/index.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/index.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-scoped-loader/index.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/wrap-loader/index.js",  
]

为什么会使用这个 h5-vue-style-loader?

用了 alias

/node_modules/@dcloudio/vue-cli-plugin-uni/lib/h5/index.js文件中配置了webpack

resolveLoader: {  
    alias: {  
      'vue-style-loader': resolve('packages/h5-vue-style-loader')  
    }  
  }

在 h5-vue-style-loader中 处理 css模块时,
编译源码是

var code = [  
  '// add the styles to the DOM',  
  'var add = require(' + addStylesClientPath + ').default',  
  'var update = add(' + id + ', content, ' + isProduction + ', ' + JSON.stringify(options) + ');'  
]

动态 插入了 add/update 方法
执行后的返回示例:

// style-loader: Adds some css to the DOM by adding a <style> tag  

// load the styles  
var content = require("........!../node_modules/@dcloudio/vue-cli-plugin-uni/packages/wrap-loader/index.js??clonedRuleSet-45[0].rules[0].use!./App.vue?vue&type=style&index=0&lang=scss&");  

if(content.__esModule) content = content.default;  

if(typeof content === 'string') content = [[module.id, content, '']];  
if(content.locals) module.exports = content.locals;  

// add the styles to the DOM  
var add = require("!../node_modules/@dcloudio/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/addStylesClient.js").default  
var update = add("43b7a677", content, true, {"sourceMap":false,"shadowMode":false});

也就是 这个 css 模块 变成了 上面的样子

运行时呢?

css模块 代码 注入了
var add = require("!../node_modules/@dcloudio/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/addStylesClient.js").default

源码是:

var UPX_RE = /%\?([+-]?\d+(\.\d+)?)\?%/g;  
function processCss(css) {  
    var page = getPage();  
    if (typeof uni !== "undefined" && !uni.canIUse("css.var")) {  
        //不支持 css 变量  
        var offset = getWindowOffset();  
        css = css  
            .replace(VAR_STATUS_BAR_HEIGHT, "0px")  
            .replace(VAR_WINDOW_TOP, offset.top + "px")  
            .replace(VAR_WINDOW_BOTTOM, offset.bottom + "px")  
            .replace(VAR_WINDOW_LEFT, "0px")  
            .replace(VAR_WINDOW_RIGHT, "0px");  
    }  
    return css  
        .replace(BODY_SCOPED_RE, page)  
        .replace(BODY_RE, "")  
        .replace(PAGE_SCOPED_RE, "body." + page + " uni-page-body")  
        .replace(/\{[\s\S]+?\}|@media.+?\{/g, function (css) {  
            if (typeof uni === "undefined") {  
                return css;  
            }  
            // 这里 把  %?数值?% 格式的  数字样式 使用 upx2px 计算成px  
            return css.replace(UPX_RE, function (a, b) {  
                return uni.upx2px(b) + "px";  
            });  
        });  
}
继续阅读 »

vue3 + vite

vue3 下 , h5使用rpx 时, 会 编译成 rem

注册 postcss 的 plugin

在/node_modules/@dcloudio/uni-h5-vite/dist/plugin/config.js,
代码是, 用的 是config 这个钩子

 css: {  
    postcss: {  
        plugins: (0, uni_cli_shared_1.initPostcssPlugin)({  
            uniApp: (0, uni_cli_shared_1.parseRpx2UnitOnce)(inputDir, process.env.UNI_PLATFORM),  
        }),  
    },  
},

parseRpx2UnitOnce , 选定使用的单位

exports.parseRpx2UnitOnce = (0, uni_shared_1.once)((inputDir, platform = 'h5') => {  
    // 如果是  h5/app/鸿蒙 会使用 defaultRpx2Unit  
    const rpx2unit = platform === 'h5' || platform === 'app' || platform === 'app-harmony'  
        ? uni_shared_1.defaultRpx2Unit  
        : uni_shared_1.defaultMiniProgramRpx2Unit;  
    const manifestJson = (0, exports.parseManifestJsonOnce)(inputDir);  
    let platformOptions = getPlatformManifestJson(manifestJson, platform);  
    if (platformOptions && platformOptions.rpx) {  
        return (0, shared_1.extend)({}, rpx2unit, platformOptions);  
    }  
    return (0, shared_1.extend)({}, rpx2unit);  
});

都有啥呢 ?

const defaultRpx2Unit = {  
    unit: 'rem',  
    unitRatio: 10 / 320,  
    unitPrecision: 5,  
};  
const defaultMiniProgramRpx2Unit = {  
    unit: 'rpx',  
    unitRatio: 1,  
    unitPrecision: 1,  
};

但是 注意这里 let platformOptions = getPlatformManifestJson(manifestJson, platform);
还是 会从 mainfest中 获取 配置的, 如果有 , 就用 mainfest 中的,
也就是 你可以 在 manifest.json的 h5节点下 , 覆盖 一些 配置 , 例如

    "h5": {  
        "router": {  
            "mode": "history"  
        },  
        "unit": "px",  
        "unitRatio": 0.5,  
        "unitPrecision": 2,  
    }

但是 文档里 , 我没有 找到

哪里 修改的 rpx 2 rem 呢?

在这里 /node_modules/@dcloudio/uni-cli-shared/dist/postcss/plugins/uniapp.js

const uniapp = (opts) => {  
    const platform = process.env.UNI_PLATFORM;  
    const { unit, unitRatio, unitPrecision } = (0, shared_1.extend)({}, defaultUniAppCssProcessorOptions, opts);  
    const rpx2unit = (0, uni_shared_1.createRpx2Unit)(unit, unitRatio, unitPrecision);  
    return {  
        postcssPlugin: 'uni-app',  
        prepare() {  
            return {  
                OnceExit(root) {  
                    root.walkDecls(walkDecls(rpx2unit));  
                    const rewriteTag = transforms[platform];  
                    filterPrefersColorScheme(root);  
                    if (rewriteTag) {  
                        root.walkRules(walkRules({  
                            rewriteTag,  
                        }));  
                    }  
                },  
            };  
        },  
    };  
};

就是 遍历 然后 替换

function walkDecls(rpx2unit) {  
    return (decl) => {  
        const { value } = decl;  
        if (value.indexOf('rpx') === -1 && value.indexOf('upx') === -1) {  
            return;  
        }  
        // 如果有 rpx 或者upx, 就调用rpx2unit  
        decl.value = rpx2unit(decl.value);  
    };  
}
const unitRE = new RegExp(`"[^"]+"|'[^']+'|url\\([^)]+\\)|(\\d*\\.?\\d+)[r|u]px`, 'g');  

// 这里的  参数 就是  defaultRpx2Unit的三个参数  
function createRpx2Unit(unit, unitRatio, unitPrecision) {  
    // ignore: rpxCalcIncludeWidth  
    return (val) => val.replace(unitRE, (m, $1) => {  
        if (!$1) {  
            return m;  
        }  
        if (unitRatio === 1) {  
            return `${$1}${unit}`;  
        }  
        // 替换 为 rem  
        // 就是  * unitRatio, 然后 保留unitPrecision 位的小数  
        const value = toFixed(parseFloat($1) * unitRatio, unitPrecision);  
        return value === 0 ? '0' : `${value}${unit}`;  
    });  
}

我是 分割线----------------------------------------------------------------------------------------------------------------------------------------------------------------

vue2 + webpack

再 说一下 vue2的 处理, vue2 是 依托于 vue-cli-service

查看打包结果

写一个 最简单的 项目,
查看 打包后的 结果

 ___CSS_LOADER_EXPORT___.push([  
            module.id,  
            '@charset "UTF-8";\n/**\n  */.ggdxd[data-v-4551d3b2]{height:%?600?%;background-color:pink}',  
            "",  
        ]);

是 内联css ,
而 可以 修改么? 可以 在 vue.config.js中 设置css.extract么?

不可以

查看代码, uni 是 使用 自定义 的 vue-cli-service 插件,
/node_modules/@dcloudio/vue-cli-plugin-uni/index.js

h5 强制要 内联css...

if (process.env.UNI_PLATFORM === 'h5' || process.env.UNI_USING_V3) {  
    options.css.extract = false  
} else {  
    options.css.extract = true  
}

height:%?600?%

在 cli 项目中, 根目录下会有postcss.config.js
实际上 使用了 uni的 一个自定义 插件require('@dcloudio/vue-cli-plugin-uni/packages/postcss')
在 parseWord方法中

if (process.env.UNI_PLATFORM === 'h5') {  
    if (u === 'upx' || u === 'rpx') {  
          // 这里 变成了很奇怪的东西  
      node.value = `%?${num}?%`  
    }  
}

也就是 在编译的产物中, rpx/upx 都转成了 %?${num}?%的 格式

啥时候 转成 px 哦?

是 运行时!

运行时的 转换代码 是哪里来的?

是 通过 webpack的 loader 处理的

我写了一个 webpack 插件, 获取了 resolve 之后的 样式使用的loader

[  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/pitcher.js",  

  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/h5-vue-style-loader/index.js",  

  "/node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader/index.js",  
  "/node_modules/postcss-loader/dist/cjs.js",  
  "/node_modules/postcss-loader/dist/cjs.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/sass-loader/dist/cjs.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-preprocess-loader/index.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/index.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/webpack-scoped-loader/index.js",  
  "/node_modules/@dcloudio/vue-cli-plugin-uni/packages/wrap-loader/index.js",  
]

为什么会使用这个 h5-vue-style-loader?

用了 alias

/node_modules/@dcloudio/vue-cli-plugin-uni/lib/h5/index.js文件中配置了webpack

resolveLoader: {  
    alias: {  
      'vue-style-loader': resolve('packages/h5-vue-style-loader')  
    }  
  }

在 h5-vue-style-loader中 处理 css模块时,
编译源码是

var code = [  
  '// add the styles to the DOM',  
  'var add = require(' + addStylesClientPath + ').default',  
  'var update = add(' + id + ', content, ' + isProduction + ', ' + JSON.stringify(options) + ');'  
]

动态 插入了 add/update 方法
执行后的返回示例:

// style-loader: Adds some css to the DOM by adding a <style> tag  

// load the styles  
var content = require("........!../node_modules/@dcloudio/vue-cli-plugin-uni/packages/wrap-loader/index.js??clonedRuleSet-45[0].rules[0].use!./App.vue?vue&type=style&index=0&lang=scss&");  

if(content.__esModule) content = content.default;  

if(typeof content === 'string') content = [[module.id, content, '']];  
if(content.locals) module.exports = content.locals;  

// add the styles to the DOM  
var add = require("!../node_modules/@dcloudio/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/addStylesClient.js").default  
var update = add("43b7a677", content, true, {"sourceMap":false,"shadowMode":false});

也就是 这个 css 模块 变成了 上面的样子

运行时呢?

css模块 代码 注入了
var add = require("!../node_modules/@dcloudio/vue-cli-plugin-uni/packages/h5-vue-style-loader/lib/addStylesClient.js").default

源码是:

var UPX_RE = /%\?([+-]?\d+(\.\d+)?)\?%/g;  
function processCss(css) {  
    var page = getPage();  
    if (typeof uni !== "undefined" && !uni.canIUse("css.var")) {  
        //不支持 css 变量  
        var offset = getWindowOffset();  
        css = css  
            .replace(VAR_STATUS_BAR_HEIGHT, "0px")  
            .replace(VAR_WINDOW_TOP, offset.top + "px")  
            .replace(VAR_WINDOW_BOTTOM, offset.bottom + "px")  
            .replace(VAR_WINDOW_LEFT, "0px")  
            .replace(VAR_WINDOW_RIGHT, "0px");  
    }  
    return css  
        .replace(BODY_SCOPED_RE, page)  
        .replace(BODY_RE, "")  
        .replace(PAGE_SCOPED_RE, "body." + page + " uni-page-body")  
        .replace(/\{[\s\S]+?\}|@media.+?\{/g, function (css) {  
            if (typeof uni === "undefined") {  
                return css;  
            }  
            // 这里 把  %?数值?% 格式的  数字样式 使用 upx2px 计算成px  
            return css.replace(UPX_RE, function (a, b) {  
                return uni.upx2px(b) + "px";  
            });  
        });  
}
收起阅读 »

腾讯云直播SDK 推流直播 + 点播查看 悬浮窗应用内外悬浮窗

插件开发

是原生SDK 有需要的联系我

是原生SDK 有需要的联系我