HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

uniapp电影app作品展示 分享

uniapp

从当初的 5+ 到 uniapp第一版 流应用 ,到现在最新uni-app,一直使用dc家 的产品制作app。
最近做了个影视app玩,不得不说uniapp确实强大。


首页用的vue写的,轮播也是再hllo uniapp 找的。顺便做了个下拉刷新。

分类 页页很方便。上拉加载更多,一句代码就解决了。

至于播放器,功能页很多,也可以直接用官方的。当然播放器肯定也能播放 直播流。
倍速,投屏,弹幕,自然都可以实现。
这里的难点 我想就是线路切换问题,很容易绕晕。
而且很多人有解析,有切片,有的还是对接别人的api,也有一次传完数据,也有点一集传一集的api。


搜索界面使用的 nvue ,这里用到了input ,这些几乎都不用写,直接导入复制黏贴就行。
打开页面 自带加载效果。

再说说网页功能,uniapp已经集成 x5内核,同时影视站长关心的网页播放器也得到了解决
上面界面就是和腾讯产品里的播放器一模一样。
好了,介绍这么多。希望大家支持国产,有兴趣的伙伴可以加入我们的qq群343440607,一起开发app

继续阅读 »

从当初的 5+ 到 uniapp第一版 流应用 ,到现在最新uni-app,一直使用dc家 的产品制作app。
最近做了个影视app玩,不得不说uniapp确实强大。


首页用的vue写的,轮播也是再hllo uniapp 找的。顺便做了个下拉刷新。

分类 页页很方便。上拉加载更多,一句代码就解决了。

至于播放器,功能页很多,也可以直接用官方的。当然播放器肯定也能播放 直播流。
倍速,投屏,弹幕,自然都可以实现。
这里的难点 我想就是线路切换问题,很容易绕晕。
而且很多人有解析,有切片,有的还是对接别人的api,也有一次传完数据,也有点一集传一集的api。


搜索界面使用的 nvue ,这里用到了input ,这些几乎都不用写,直接导入复制黏贴就行。
打开页面 自带加载效果。

再说说网页功能,uniapp已经集成 x5内核,同时影视站长关心的网页播放器也得到了解决
上面界面就是和腾讯产品里的播放器一模一样。
好了,介绍这么多。希望大家支持国产,有兴趣的伙伴可以加入我们的qq群343440607,一起开发app

收起阅读 »

想购买几个已上架有一定用户访问量的uniapp

源码分享

想购买几个已上架有一定用户访问量的uniapp
感兴趣的加下微信,done2008

想购买几个已上架有一定用户访问量的uniapp
感兴趣的加下微信,done2008

pages.json 解耦 助力 uni-app 模块化编程---uni-dev-tools

uni_app

uni-dev-tools 是什么

uni-dev-tools是一个辅助开发 uni-app 的旁路辅助开发工具。对uni-app原目录设计只做优化,不做侵入。他不是开发框架,也不是插件。
该工具只为简化开发人员工作,优化多人开发模式,负责将pages.json中的配置分解再合并的自动化工作。
解决pages.json混乱的问题。因此pages.json不需要提交,pages.json 将会由其他文件自动合并生成。

pages.json 痛点

1.公有、私有混合,造成模块化开发,移植困难
2.团队开发,多人同时编辑该文件,代码提交,签出遇到若干问题
3.假若系统有50个view,那么pages.json 将会有1公里那么长,问谁能维护?

uni-dev-tools 的愿望

1.满足系统功能模块化;
2.全局与私有解耦合;
3.避免团队开发同时编辑一个文件;
4.方便模块移植;
5.我希望的uni-app框架结构为:pages文件夹为各模块的根目录,其中一个文件夹就是一个模块,里面包含视图层,逻辑层,私有路由配置文件。各功能模块的私有化配置,仅局限在各自的目录下,不与框架目录产生耦合关系。各开发人员的工作空间仅限于当前模块的工作目录。

使用 uni-dev-tools 后,你的 uni-app 目录结构可以这样

目录结构不限于以上,您可以按照自己的习惯,进行构建。如果您需要改造uni-app的目录,请注意下面

uni-dev-tools 监控以下目录

pages config workers sub-packages

uni-dev-tools 监控以下文件

router.json,condition.json,easy-com.json,global-style.json,config.json,tab-bar.json,preload-rule.json,sub-packages.json

所以,只要您的目录是以上目录,并且文件名是以上所列,无论你在json文件中方什么,都会自动合并到pages.json,所以目录结构您可以自己发挥。

因此 uni-dev-tools 干了以下这些事

1.应用根目录下增加了 config 目录,里面存放系统的全局配置文件,比如:condition.json,easy-com.json,global-style.json,tab-bar.json,通过各json文件的文件名可以看出,是对应pages.json 中的 各配置节点。

2.如果存在workers目录,在该目录下生成 config.json ,对应 pages.json 中的 workers 属性配置。

3.应用根目录下创建分包目录 sub-packages,并生成 preload-rule.json 对应 pages.json 中的preloadRule 分包下载规则 属性。今后所有分包都放在这个文件夹下,一个目录一个包,在该包下创建router.json文件,可对应pages.json 中的subPackages属性配置。

4.pages目录中存放主包页面模块,一个文件夹一个模块,该文件夹下的router.json 对应 pages.json 中的 pages 属性配置。

5.如果您对于以上的目录设计不满意,您可以自己进行精简,uni-dev-tools 监控的目录为"pages config workers sub-packages",监控的文件名为"router.json,condition.json,easy-com.json,global-style.json,config.json,tab-bar.json,preload-rule.json",

只要你确保是这项文件名和目录名,配置文件放置的层级结构你可以自定。比如你可以只创建config文件夹,并包配置都放在这个文件夹下,也是可以的啦。不需要强制按照我的目录编排。

6.监控以上各目录文件,发生新建或修改时,自动拉取配置,合并生成 pages.json

你要如何做

转到应用根目录下,运行

npm install uni-dev-tools  

//对应用进行初始化,从pages.json 中分解各个属性节点,生成各个配置文件  
npx uni-dev-tools init  

//对文件进行监控,自动将各文件中的配置信息合并到pages.json中  
npx uni-dev-tools watch  

第一次

请先进行初始化,将pages.json中的配置分解到各个配置文件,如果不这么做,直接 watch,您的pages.json 有可能会被您创建的空json文件覆盖。

下一步,你可以做什么

删除 pages.json

bug 提交 新需求提交

https://github.com/try520/uni-dev-tools/issues

继续阅读 »

uni-dev-tools 是什么

uni-dev-tools是一个辅助开发 uni-app 的旁路辅助开发工具。对uni-app原目录设计只做优化,不做侵入。他不是开发框架,也不是插件。
该工具只为简化开发人员工作,优化多人开发模式,负责将pages.json中的配置分解再合并的自动化工作。
解决pages.json混乱的问题。因此pages.json不需要提交,pages.json 将会由其他文件自动合并生成。

pages.json 痛点

1.公有、私有混合,造成模块化开发,移植困难
2.团队开发,多人同时编辑该文件,代码提交,签出遇到若干问题
3.假若系统有50个view,那么pages.json 将会有1公里那么长,问谁能维护?

uni-dev-tools 的愿望

1.满足系统功能模块化;
2.全局与私有解耦合;
3.避免团队开发同时编辑一个文件;
4.方便模块移植;
5.我希望的uni-app框架结构为:pages文件夹为各模块的根目录,其中一个文件夹就是一个模块,里面包含视图层,逻辑层,私有路由配置文件。各功能模块的私有化配置,仅局限在各自的目录下,不与框架目录产生耦合关系。各开发人员的工作空间仅限于当前模块的工作目录。

使用 uni-dev-tools 后,你的 uni-app 目录结构可以这样

目录结构不限于以上,您可以按照自己的习惯,进行构建。如果您需要改造uni-app的目录,请注意下面

uni-dev-tools 监控以下目录

pages config workers sub-packages

uni-dev-tools 监控以下文件

router.json,condition.json,easy-com.json,global-style.json,config.json,tab-bar.json,preload-rule.json,sub-packages.json

所以,只要您的目录是以上目录,并且文件名是以上所列,无论你在json文件中方什么,都会自动合并到pages.json,所以目录结构您可以自己发挥。

因此 uni-dev-tools 干了以下这些事

1.应用根目录下增加了 config 目录,里面存放系统的全局配置文件,比如:condition.json,easy-com.json,global-style.json,tab-bar.json,通过各json文件的文件名可以看出,是对应pages.json 中的 各配置节点。

2.如果存在workers目录,在该目录下生成 config.json ,对应 pages.json 中的 workers 属性配置。

3.应用根目录下创建分包目录 sub-packages,并生成 preload-rule.json 对应 pages.json 中的preloadRule 分包下载规则 属性。今后所有分包都放在这个文件夹下,一个目录一个包,在该包下创建router.json文件,可对应pages.json 中的subPackages属性配置。

4.pages目录中存放主包页面模块,一个文件夹一个模块,该文件夹下的router.json 对应 pages.json 中的 pages 属性配置。

5.如果您对于以上的目录设计不满意,您可以自己进行精简,uni-dev-tools 监控的目录为"pages config workers sub-packages",监控的文件名为"router.json,condition.json,easy-com.json,global-style.json,config.json,tab-bar.json,preload-rule.json",

只要你确保是这项文件名和目录名,配置文件放置的层级结构你可以自定。比如你可以只创建config文件夹,并包配置都放在这个文件夹下,也是可以的啦。不需要强制按照我的目录编排。

6.监控以上各目录文件,发生新建或修改时,自动拉取配置,合并生成 pages.json

你要如何做

转到应用根目录下,运行

npm install uni-dev-tools  

//对应用进行初始化,从pages.json 中分解各个属性节点,生成各个配置文件  
npx uni-dev-tools init  

//对文件进行监控,自动将各文件中的配置信息合并到pages.json中  
npx uni-dev-tools watch  

第一次

请先进行初始化,将pages.json中的配置分解到各个配置文件,如果不这么做,直接 watch,您的pages.json 有可能会被您创建的空json文件覆盖。

下一步,你可以做什么

删除 pages.json

bug 提交 新需求提交

https://github.com/try520/uni-dev-tools/issues

收起阅读 »

uniapp推出小程序SDK,会是一场技术驱动的行业变革吗?

小程序SDK uniapp

背景
2020年2月8日,著名跨端开发技术框架uniapp发布小程序SDK。借用官方的一句话来解释这个SDK的功能:
“uni小程序SDK,是一个用于原生App中集成的SDK,它可以帮助原生App快速实现小程序的能力”
作为一个已经被业界认可的跨端开发技术框架,uniapp又在跨端开发的道路上向前迈进了一大步。
此次小程序sdk的发布,标志着小程序技术领域的全面竞争时代来临。
它可以让众多原生app以极低的技术成本,构建自己的小程序生态(注意,是自己的)。它从技术端解决了小程序生态构建的基础设施问题。
笔者长年从事软件开发行业,于19年开始入坑uniapp,用于替代传统的vue的技术方案。在生产环境下,实现了h5,小程序,app的多端快速低成本的开发。
技术驱动革新
未来基于uniapp的应用将会获得一个全新的应用场景——无缝嵌入各种原生app,这是一种挑战h5集成难易度的方案。
总所周知,传统app集成大多采用SDK封装、webview内嵌、接口对接这3种方案。然而这些方案往往在开发成本、使用体验方面都难以得到比较好的平衡。
1.SDK封装方式。适合偏底层的业务,比如各种直播SDK、IMSDK、推送SDK。然而对于一些重业务的应用来说,SDK方式集成存在比较大的缺陷,不同的终端需要开发不同的SDK。能否抽出业务层是开发者比较关心的问题。以往面对比较大的业务应用,封装成SDK显然不合适。
2.Webview内嵌形式,体验糟糕,网页的体验终归是在服务端,即便是采用了vue构建SPA单页应用,仍然难以解决与原生的相互调用问题。受制于webview的能力,很多页面切换的效果都不理想。
3.接口对接方式,无疑是可以获得最佳的体验,但是也是最高成本的,目前app开发,很大一部分工作均在业务前端,如果通过接口对接,那么对于app的开发者来说,其存在的意义仅限于节省后端开发人力。
综合上述三种常见的集成方式,一种体验优秀,成本低廉的集成模式一直被业界需求,单也一直未被满足。
uniapp小程序SDK似乎就是捕捉到了这种需求,顺势而为,推出小程序SDK。目前开源程度仅限于大厂商单独获取源码。
实践
笔者在从业早期,也学习过安卓应用的开发,所以自己动手搭建了一套安卓的开发环境。多年未从事安卓开发,搭建环境的过程也是非常坎坷。不过最终还是成功运行了uniapp提供的项目示例。
先上一个官方的示例:


下面是笔者进行改造后,将一个自己公司的产品进行对接。通过判断勾选的单选框,设置不同的appid,从而打开不同的界面。


可以看到,我们成功打开了自己开发的应用。并且还可以直接启动至对应的子页面。
这边再讲一下直接打开子页面的应用场景。
在进行业务对接的过程中。比如开发者的应用场景是自己原有的业务app上对接一个社区,来做社区化运营,那么这个时候,我们往往会做一个应用场景就是他需要在app原有的界面内,植入一个发布按钮。点击该按钮,可以直接打开社区,并跳转到发布界面。
这样的体验是非常棒的。
对应的启动代码:

如何夹带启动参数?

上面这段代码是设置一个参数a,值为1,在启动的时候作为启动参数。
在uniapp当中,只需要通过对应的api获取到这个参数。
在开发当中,开发者很关心宿主程序如何与内嵌的应用进行交互。尤其是我们在做用户免登陆这个需求的时候,h5 webview方式只需要在url当中,夹带当前用户的token,即可实现免登陆。那么uniapp这边可以通过启动参数的形式优雅地实现这个需求。
除此之外,官方还提供了一套完整的小程序SDK的api文档,供开发者查阅。笔者初步看了一下,可以实现一些常规性的界面UI的调整。满足不同的业务场景使用。同时也提供了一些关闭、触发的回调函数。基本可以满足业务需求。
缺点?
经过笔者真机测试。将我们的产品短说社区系统1.9.0完整版本实际置入后。得到了一个较为不错的表现,但是仍有不足。
首先是v3编译器,uniapp近期推出的最新的编译器,官方称提升了性能等等,由于历史原因,短说社区基于老的编译器开发,在真机测试中,在V3下存在一点样式兼容问题。导致了些许错位。
在打包资源后,置入演示demo,发现小程序SDK环境下运行后,同样存在样式错位问题。但是所幸整体交互还算可以。运行较为流畅,主干功能未受影响。
实战下来,总体感觉uniapp目前提供的小程序SDK有以下几个不足之处:
1.编译测试较为麻烦,目前只能在开发环境下,模拟运行小程序版本,测试无大问题后,将资源包导出后放进app。再进行真机调试。如果编译差异不存在,那么这样的调试也基本可以接受。就怕存在一些编译差异,导致一些摸不到头脑的坑。
2.V3编译器自身的向下兼容问题。相信一些基于v3开发的应用不存在这个问题,但是对于一些有些积累的APP,譬如笔者公司的产品来说,就比较头疼了。需要逐个调试,进行调整修复。笔者测试了老版本编译器,错位极其严重。而使用v3后,有所改观。证明编译器和sdk本身就是在一个完善过程中。
3.包的大小问题,由于笔者手上的是官方提供的演示案例。所以无法进行前后比较。但是从官网评论来看,有开发者发现集成这个小程序SDK后,包体积大了48MB,也有人通过缩减功能只增加了12MB。倒是导出的资源包体积还可接受,基本可以忽略。
4.动态下载和加载资源包的问题,目前官网还未有明确的文档说明。如果可以实现动态下载资源包并且运行,意味着可以实现像微信小程序这样的生态。想象空间非常大。尤其对于有千万级用户的app来说,吸引力巨大。
5.API目前虽然还不错,但是还需给一些发展时间。对于复杂的应用场景,还需要更多的API支撑。
6.目前由于官方的开源策略,需要app厂家自行与官方沟通获得小程序SDK源码,官方注明是没有费用的。
最后
目前国内互联网市场,增量难以获得,且成本高昂,在存量市场下,如何开拓更多的业务场景,以更低成本更轻快的速度集成现成的软件厂商提供的应用是未来几年的一个重要应用场景。
Uniapp此番推出的小程序SDK,如果能够坚持做下去,终有一天走出实验室,投入到生产环境中。
未来已来,技术问题解决了,剩下的就是比拼运营实力的时候了。国内app厂商,是时候考虑一下未来的方向了。
作者:奕潇(微信号yixiao100),短说OSX社区论坛系统产品总监,5年社交社区类产品管理经验。想天软件创始人。

继续阅读 »

背景
2020年2月8日,著名跨端开发技术框架uniapp发布小程序SDK。借用官方的一句话来解释这个SDK的功能:
“uni小程序SDK,是一个用于原生App中集成的SDK,它可以帮助原生App快速实现小程序的能力”
作为一个已经被业界认可的跨端开发技术框架,uniapp又在跨端开发的道路上向前迈进了一大步。
此次小程序sdk的发布,标志着小程序技术领域的全面竞争时代来临。
它可以让众多原生app以极低的技术成本,构建自己的小程序生态(注意,是自己的)。它从技术端解决了小程序生态构建的基础设施问题。
笔者长年从事软件开发行业,于19年开始入坑uniapp,用于替代传统的vue的技术方案。在生产环境下,实现了h5,小程序,app的多端快速低成本的开发。
技术驱动革新
未来基于uniapp的应用将会获得一个全新的应用场景——无缝嵌入各种原生app,这是一种挑战h5集成难易度的方案。
总所周知,传统app集成大多采用SDK封装、webview内嵌、接口对接这3种方案。然而这些方案往往在开发成本、使用体验方面都难以得到比较好的平衡。
1.SDK封装方式。适合偏底层的业务,比如各种直播SDK、IMSDK、推送SDK。然而对于一些重业务的应用来说,SDK方式集成存在比较大的缺陷,不同的终端需要开发不同的SDK。能否抽出业务层是开发者比较关心的问题。以往面对比较大的业务应用,封装成SDK显然不合适。
2.Webview内嵌形式,体验糟糕,网页的体验终归是在服务端,即便是采用了vue构建SPA单页应用,仍然难以解决与原生的相互调用问题。受制于webview的能力,很多页面切换的效果都不理想。
3.接口对接方式,无疑是可以获得最佳的体验,但是也是最高成本的,目前app开发,很大一部分工作均在业务前端,如果通过接口对接,那么对于app的开发者来说,其存在的意义仅限于节省后端开发人力。
综合上述三种常见的集成方式,一种体验优秀,成本低廉的集成模式一直被业界需求,单也一直未被满足。
uniapp小程序SDK似乎就是捕捉到了这种需求,顺势而为,推出小程序SDK。目前开源程度仅限于大厂商单独获取源码。
实践
笔者在从业早期,也学习过安卓应用的开发,所以自己动手搭建了一套安卓的开发环境。多年未从事安卓开发,搭建环境的过程也是非常坎坷。不过最终还是成功运行了uniapp提供的项目示例。
先上一个官方的示例:


下面是笔者进行改造后,将一个自己公司的产品进行对接。通过判断勾选的单选框,设置不同的appid,从而打开不同的界面。


可以看到,我们成功打开了自己开发的应用。并且还可以直接启动至对应的子页面。
这边再讲一下直接打开子页面的应用场景。
在进行业务对接的过程中。比如开发者的应用场景是自己原有的业务app上对接一个社区,来做社区化运营,那么这个时候,我们往往会做一个应用场景就是他需要在app原有的界面内,植入一个发布按钮。点击该按钮,可以直接打开社区,并跳转到发布界面。
这样的体验是非常棒的。
对应的启动代码:

如何夹带启动参数?

上面这段代码是设置一个参数a,值为1,在启动的时候作为启动参数。
在uniapp当中,只需要通过对应的api获取到这个参数。
在开发当中,开发者很关心宿主程序如何与内嵌的应用进行交互。尤其是我们在做用户免登陆这个需求的时候,h5 webview方式只需要在url当中,夹带当前用户的token,即可实现免登陆。那么uniapp这边可以通过启动参数的形式优雅地实现这个需求。
除此之外,官方还提供了一套完整的小程序SDK的api文档,供开发者查阅。笔者初步看了一下,可以实现一些常规性的界面UI的调整。满足不同的业务场景使用。同时也提供了一些关闭、触发的回调函数。基本可以满足业务需求。
缺点?
经过笔者真机测试。将我们的产品短说社区系统1.9.0完整版本实际置入后。得到了一个较为不错的表现,但是仍有不足。
首先是v3编译器,uniapp近期推出的最新的编译器,官方称提升了性能等等,由于历史原因,短说社区基于老的编译器开发,在真机测试中,在V3下存在一点样式兼容问题。导致了些许错位。
在打包资源后,置入演示demo,发现小程序SDK环境下运行后,同样存在样式错位问题。但是所幸整体交互还算可以。运行较为流畅,主干功能未受影响。
实战下来,总体感觉uniapp目前提供的小程序SDK有以下几个不足之处:
1.编译测试较为麻烦,目前只能在开发环境下,模拟运行小程序版本,测试无大问题后,将资源包导出后放进app。再进行真机调试。如果编译差异不存在,那么这样的调试也基本可以接受。就怕存在一些编译差异,导致一些摸不到头脑的坑。
2.V3编译器自身的向下兼容问题。相信一些基于v3开发的应用不存在这个问题,但是对于一些有些积累的APP,譬如笔者公司的产品来说,就比较头疼了。需要逐个调试,进行调整修复。笔者测试了老版本编译器,错位极其严重。而使用v3后,有所改观。证明编译器和sdk本身就是在一个完善过程中。
3.包的大小问题,由于笔者手上的是官方提供的演示案例。所以无法进行前后比较。但是从官网评论来看,有开发者发现集成这个小程序SDK后,包体积大了48MB,也有人通过缩减功能只增加了12MB。倒是导出的资源包体积还可接受,基本可以忽略。
4.动态下载和加载资源包的问题,目前官网还未有明确的文档说明。如果可以实现动态下载资源包并且运行,意味着可以实现像微信小程序这样的生态。想象空间非常大。尤其对于有千万级用户的app来说,吸引力巨大。
5.API目前虽然还不错,但是还需给一些发展时间。对于复杂的应用场景,还需要更多的API支撑。
6.目前由于官方的开源策略,需要app厂家自行与官方沟通获得小程序SDK源码,官方注明是没有费用的。
最后
目前国内互联网市场,增量难以获得,且成本高昂,在存量市场下,如何开拓更多的业务场景,以更低成本更轻快的速度集成现成的软件厂商提供的应用是未来几年的一个重要应用场景。
Uniapp此番推出的小程序SDK,如果能够坚持做下去,终有一天走出实验室,投入到生产环境中。
未来已来,技术问题解决了,剩下的就是比拼运营实力的时候了。国内app厂商,是时候考虑一下未来的方向了。
作者:奕潇(微信号yixiao100),短说OSX社区论坛系统产品总监,5年社交社区类产品管理经验。想天软件创始人。

收起阅读 »

完美解决区块链ether.js无法随机生成钱包,报错:error:Error: platform missing String.prototype.normalize

uniapp

问题描述

这个错误iPhone或H5可以正常随机生成钱包,仅Android会出现这个问题(不能正常生成随机钱包)

区块链异步异常捕捉  
_error:Error: platform missing String.prototype.normalize  
 (operation="String.prototype.normalize", form="missing NFKD", version=4.0.27)  

解决方案【运行环境为Hbuilder X2.4.6】

官方解释:这个ES6的API存在兼容问题,使用es6时需注意兼容性

解决方式参考:
https://ext.dcloud.net.cn/plugin?id=955

完整步骤

  1. 下载normalize-demo
  2. 解压后在项目中 App.vue 引入 unorm.js
  3. 直接连接Android手机调试即可
  4. 如有帮助,感谢点赞
继续阅读 »

问题描述

这个错误iPhone或H5可以正常随机生成钱包,仅Android会出现这个问题(不能正常生成随机钱包)

区块链异步异常捕捉  
_error:Error: platform missing String.prototype.normalize  
 (operation="String.prototype.normalize", form="missing NFKD", version=4.0.27)  

解决方案【运行环境为Hbuilder X2.4.6】

官方解释:这个ES6的API存在兼容问题,使用es6时需注意兼容性

解决方式参考:
https://ext.dcloud.net.cn/plugin?id=955

完整步骤

  1. 下载normalize-demo
  2. 解压后在项目中 App.vue 引入 unorm.js
  3. 直接连接Android手机调试即可
  4. 如有帮助,感谢点赞
收起阅读 »

小程序分享时候,不能分享自定义图片。

小程序分享时候,不能分享自定义图片。每次分享得都是整个页面,而不是自定义的图片。求解决。。

小程序分享时候,不能分享自定义图片。每次分享得都是整个页面,而不是自定义的图片。求解决。。

使用uni-app进行小程云开发(腾讯云)的正确姿势

云开发

目前uni-app已经支持云开发了,但是遗憾的是目前只支持阿里云。如果项目主要是微信小程序,其实首选还是腾讯云。但是我又想很方便的使用uni-app进行小程序开发,所以今天就尝试了一下,然后初步试了一下,结论是:很爽!

第一步:使用微信开发者工具新建小程序项目a,选择云开发

假设项目目录为:D:\mini-app

第二步:在HBuilderX里新建一个uni-app项目b,注意不要勾选云开发,因为目前uni-app只支持阿里云。

假设项目目录为:D:\uni-app

第三步:将小程序根目录D:\mini-app\a下的所有文件复制到uni-app项目根目录D:\uni-app\b下(其实反过来将uni-app项目复制到小程序项目理论上也行,只是第五步的操作会变成将小程序项目拖入到Hbulderx中,只是不确定HBuilderX能否正确识别项目类型,未尝试)

第四步:复制完成后,修改uni-app项目D:\uni-app\b\project.config.json中的miniprogramRoot配置项

"miniprogramRoot": "unpackage/dist/dev/mp-weixin/",  

原来的miniprogram目录就可以删除了

第五步:删除微信开发者工具中刚创建的项目a,然后导入小程序,目录为D:\uni-app\b

这样,你就可以在HBuilderX中畅快的编写代码了,每次保存代码后微信开发者工具会自动更新重新加载!

Over!

继续阅读 »

目前uni-app已经支持云开发了,但是遗憾的是目前只支持阿里云。如果项目主要是微信小程序,其实首选还是腾讯云。但是我又想很方便的使用uni-app进行小程序开发,所以今天就尝试了一下,然后初步试了一下,结论是:很爽!

第一步:使用微信开发者工具新建小程序项目a,选择云开发

假设项目目录为:D:\mini-app

第二步:在HBuilderX里新建一个uni-app项目b,注意不要勾选云开发,因为目前uni-app只支持阿里云。

假设项目目录为:D:\uni-app

第三步:将小程序根目录D:\mini-app\a下的所有文件复制到uni-app项目根目录D:\uni-app\b下(其实反过来将uni-app项目复制到小程序项目理论上也行,只是第五步的操作会变成将小程序项目拖入到Hbulderx中,只是不确定HBuilderX能否正确识别项目类型,未尝试)

第四步:复制完成后,修改uni-app项目D:\uni-app\b\project.config.json中的miniprogramRoot配置项

"miniprogramRoot": "unpackage/dist/dev/mp-weixin/",  

原来的miniprogram目录就可以删除了

第五步:删除微信开发者工具中刚创建的项目a,然后导入小程序,目录为D:\uni-app\b

这样,你就可以在HBuilderX中畅快的编写代码了,每次保存代码后微信开发者工具会自动更新重新加载!

Over!

收起阅读 »

自定义相机,取景框大小可调整

自定义 相机权限 插件

刚开发完的自定义取景相机uniapp插件,可定义取景框大小,有需要的可以私信我 5+也可以,但是需要离线打包

继续阅读 »

刚开发完的自定义取景相机uniapp插件,可定义取景框大小,有需要的可以私信我 5+也可以,但是需要离线打包

收起阅读 »

HBuilderX: 内置浏览器新功能

内置浏览器 HBuilderX

内置浏览器新功能

HBuilderX 2.6.10+版本,内置浏览器 增加 “查找代码中对应的DOM节点” 和 “高亮浏览器内对应元素” 功能

  • 在内置浏览器,右键菜单,点击查找代码中对应的DOM节点,即可跳转到编辑器相应位置
  • 在编辑器内,右键菜单,点击高亮浏览器内对应元素, 即可在内置浏览器显示相应元素

示例

继续阅读 »

内置浏览器新功能

HBuilderX 2.6.10+版本,内置浏览器 增加 “查找代码中对应的DOM节点” 和 “高亮浏览器内对应元素” 功能

  • 在内置浏览器,右键菜单,点击查找代码中对应的DOM节点,即可跳转到编辑器相应位置
  • 在编辑器内,右键菜单,点击高亮浏览器内对应元素, 即可在内置浏览器显示相应元素

示例

收起阅读 »

uni-app黑魔法:小程序自定义组件运行到H5平台

小程序组件

引言

移动互联网的初期,囿于设备硬件性能限制,流量以原生App为主,iOS、Android是当时两大平台。

随着硬件及OS的更新换代,H5可承载的体验逐步完善,为提高开发效率、节约资源(复用代码)以及热更新等目的,Hybrid模式成为主流;以及轻应用、服务号等平台的助推,H5网页流量暴涨,成为第三大平台。

2017年1月9日,微信发布小程序,历经3年发展,在今年主题为”未完成 Always Beta“的微信公开课 PRO上,微信团队披露,2019年小程序日活跃用户超过 3 亿,全年累计成交额达8000亿,同比增长超160%。

看到小程序如此惊人的增长力,我们有理由相信,有中国特色的小程序互联网时代已经到来,微信小程序也已成为继iOS、Android、H5之后的第四大流量平台。

平台分裂,为不同平台编写相同的业务代码,是件无趣的事情。

有追求的程序员,一直在探索代码复用的方案,Hybrid App即是代表。

而在如今的小程序时代,对于同样基于WEB技术的H5和小程序,如何实现代码复用,是很多前端工程师探索的方向。业内也已有不少成熟方案,从场景上来说,大致分为三类:

  1. 基于跨端框架,从头开发,一套代码,发行多个平台,比如DCloud出品的uni-app、京东凹凸实验室的taro
  2. 复用H5代码,转换H5代码在小程序环境中执行;适用于有H5平台沉淀,未开发小程序或小程序完善度较低的开发者;
    • 美团的mpvue框架是早期探索解决这个问题的代表,但因小程序不支持dom操作,故mpvue适用于vue的无dom操作的H5代码转换;
  • 最近微信官方推出的kbone,也是为了解决“把 Web 端的代码挪到小程序环境内执行”;不过,kbone 相比 mpvue 前进了一步(当然也有了新的性能缺陷),因为:

    kbone实现了一个适配器,在适配层里模拟出了浏览器环境,让 Web 端的代码可以不做什么改动便可运行在小程序里。

    1. 复用小程序代码,转换小程序代码在web环境中运行;适用于有小程序代码沉淀,未开发H5或H5平台完善度较低的开发者;这个方向业内成熟的方案还比较少。

uni-app近期支持了小程序自定义组件运行到H5平台,是对如上第三种场景的一种探索。

需求场景

鉴于小程序的低成本获客特征,很多厂商选择先开发小程序,验证业务模式后,再扩展至H5、App等其它平台。

开发者虽可借助转换器将小程序代码转换为uni-app项目(或其它跨端框架项目),快速实现多平台发行;但不少开发者是不敢轻易决策将跨端版本替换之前线上的小程序版本的,毕竟线上版本已稳定运行了一段时间。

常选的方案是:让原生小程序版本和uni-app跨端版本并行一段时间,微信平台继续使用原生版本,其它平台使用uni-app跨端版本;经过一段时间验证uni-app版本稳定后,再使用uni-app版替换掉原生小程序版本。

在这段并行的时间内,开发者需要同时维护微信原生、uni-app两个版本,新增业务需编写两份逻辑相同的代码,重复劳动,成本叠加,如何改善?

借助uni-app 支持将微信小程序组件运行到H5平台的特性,我们给出一种思路:

  • 开发者在原生小程序项目中,将新增业务以自定义组件的方式开发,优先上线小程序;
  • 拷贝小程序组件的wxml/wxss/js/json文件到uni-app 项目下,通过uni-app的编译器及运行时,保证小程序自定义组件在H5平台的正确运行。

这个方案的好处是:

  • 优先小程序开发,毕竟小程序早已上线,有存量用户

  • 复用小程序组件,新增业务仅需开发一套代码即可,降低开发成本

不止自己开发的小程序组件,业内开源的三方小程序组件,均可复制到uni-app项目项目中,运行到H5平台。

另外,部分公司的产品经理,会要求不同平台有不同的交互,但核心业务逻辑是相同的,开发者常会通过维护不同项目的方式来满足产品经理需求。此时,采取如上方案,同样可满足多个项目复用相同业务逻辑的诉求。

实际上,uni-app之前已支持将小程序自定义组件运行到App平台,对于有小程序组件沉淀或优先小程序的开发者来说,这是个好消息,一套业务组件,快速运行到iOS、Android、H5、微信小程序这四大流量平台(实际上也可运行到QQ小程序平台)。

uni-app 引用小程序组件演示

uni-app项目中使用自定义组件的方法很简单,分为三步:

1、拷贝小程序自定义组件到uni-app项目根目录下的wxcomponents文件夹下

2、在 pages.json 对应页面的 style -> usingComponents引入组件,如:

{  
    "pages": [  
        {  
            "path": "index/index",  
            "style": {  
                "usingComponents": {  
                     "custom": "/wxcomponents/custom/index"  
                }  
            }  
        }  
    ]  
}

3、在页面中使用自定义组件,如:

<!-- 页面模板 (index.vue) -->  
<view>  
    <!-- 在页面中对自定义组件进行引用 -->  
    <custom name="uni-app"></custom>  
</view>

方案实现思路

简单介绍下uni-app的多端发行原理。

uni-app基于Vue.js runtime,页面文件遵循Vue.js 单文件组件 (SFC) 规范,天然对H5的支持比较好,发行到H5平台时,先通过vue-loader解析.vue文件,导出Vue.js 组件选项对象,然后在运行时补充规范实现:

  • 组件:框架提供内置组件(view/swiper/picker等)的实现,保证平台UI及交互的一致性
  • 接口:在H5平台封装框架接口,比如路由跳转,showToast等界面交互
  • 生命周期:Vue.js的理念是一切皆为组件,没有应用和页面的概念;框架需创造出应用及页面的概念,模拟onLaunch、onShow等钩子

uni-app发行到小程序平台时,逻辑又有不同,主要工作有2块:

  • 编译器:将.vue文件拆分成wxml/wxss/js/json4个原生页面文件
  • 运行时:Vue.js和小程序都是逻辑视图层框架,都有数据绑定功能;运行时会实现Vue.js到小程序的数据同步,及小程序到Vue.js的事件代理

小程序自定义组件类似小程序原生的页面开发,一个自定义组件同样由wxml/wxss/js/json 4个文件组成,另有单独的组件规范(如Component 构造器、Behaviors特性等)。

所以,小程序自定义组件运行到H5平台,可借助uni-app已有平台功能快速实现:

  • 编译阶段:将wxml/wxss/js/json4个文件合并为.vue文件(类似 uni-app 发行到小程序的逆过程),然后调用uni-app发行H5平台的编译过程,通过vue-loader解析.vue文件,导出 Vue.js 组件选项对象
  • 运行阶段:实现 Component 构造器、Behaviors特性,模拟自定义组件特有的生命周期

编译:转换文件(mp2vue)

小程序自定义组件发行到H5平台,在编译环节主要有2项工作:

  1. 将自定义组件的wxml/wxss/js/json 4个文件组成,编译转换成.vue文件,即小程序转vue,可简写为mp2vue

  2. 通过vue-loader解析.vue文件,导出 Vue.js 组件选项对象

其中,步骤2是Vue.js项目的标准编译过程,略过不提;我们重点阐述步骤1。

mp2vue将4个独立wxml/wxss/js/json 的文件合并成一个.vue文件,并组装成templatescriptstyle 这种三段式的结构,流程包括:

  1. wxml文件生成template节点,同时完成指令、事件等模板语法转换
  2. js/json文件生成script节点,同时完成组件注册过
  3. wxss文件生成style节点,自动转换部分css兼容语法
  4. 合并为.vue文件

具体实现上,uni-app编译前先扫描wxcomponents目录,若存在则认为有小程序自定义组件,启动文件转换工作(uni-migration插件来完成):

//加载转换器  
const migrate = require('@dcloudio/uni-migration')   
//扫描wxcomponents目录  
const wxcomponents = path.resolve(process.env.UNI_INPUT_DIR, 'wxcomponents')   
if (fs.existsSync(wxcomponents)) {   
  migrate(wxcomponents, false, {  
    silent: true   
  }) // 转换 mp-weixin 小程序组件  
}

接着开始对wxml/wxss/js/json文件逐个解析,并合并为一个.vue文件:

module.exports = function transformFile(input, options) {  
    //首先转换json文件,判断是否为组件  
  const [jsCode, isComponent] = transformJsonFile(filepath + '.json', deps)  
  options.isComponent = isComponent  
    //转换 wxml 文件  
  const [templateCode, wxsCode = '', wxsFiles = []] = transformTemplateFile(filepath + templateExtname, options)  
    //转换wxss文件  
  const styleCode = transformStyleFile(filepath + styleExtname, options, deps) || ''  
  //转换js文件  
  const scriptCode = transformScriptFile(filepath + '.js', jsCode, options, deps)  
    // 生成合并后的.vue文件源码  
  return [  
    `${commentsCode}<template>  
${templateCode}  
</template>  
${wxsCode}  
<script>  
${scriptCode}  
</script>  
<style platform="mp-weixin">  
${styleCode}  
</style>`,  
    deps,  
    wxsFiles  
  ]  
}

进一步细节说明,wxml文件转为template节点时,需完成各项指令、事件等模板语法的转换,例如:

小程序自定义组件 Vue组件 描述
wx:if v-if 条件渲染
wx:for v-for 列表渲染
bindtap @click 元素点击事件

将一个最简自定义组件,按照如上流程转换,结果示意如下:

运行时:模拟小程序组件环境

uni-app的编译器并不转换小程序组件的 JS 代码,依然保留Component构造器的写法,甚至其中的API依然是wx.开头的方式,这些都依赖uni-app在H5平台的运行时来解决,主要有如下几部分内容:

  • Component构造器:解析小程序组件的各种选项配置,转换为Vue组件定义,包括变通实现其中的差异部分,如小程序组件特有的”组件所在页面的生命周期“
  • Behaviors特性:转换为Vue的混入(mixin)
  • 数据响应:在H5平台实现setData接口及this.data.xx = yy的数据通讯机制
  • API前缀:可在运行时通过代理机制,自动将wx.xx替换为uni.xx,这个比较简单,不详述

Component构造器

uni-app在H5平台定义了一个Component函数,执行到小程序的Component构造器函数后,开始循环解析其属性,并转换成Vue组件属性,流程示意代码如下:

export function Component (options) {  
  const componentOptions = parseComponent(options)  
  componentOptions.mixins.unshift(polyfill)  
  componentOptions.mpOptions.path = global['__wxRoute']  
  initRelationsHandler(componentOptions)  
  global['__wxComponents'][global['__wxRoute']] = componentOptions  
}  

export function parseComponent (mpComponentOptions) {  
  const {  
    data,  
    options,  
    methods,  
    behaviors,  
    lifetimes,  
    observers,  
    relations,  
    properties,  
    pageLifetimes,  
    externalClasses  
  } = mpComponentOptions  

  const vueComponentOptions = {  
    mixins: [],  
    props: {},  
    watch: {},  
    mpOptions: {  
      mpObservers: []  
    }  
  }  

    // 开始逐个解析所有属性  
  parseData(data, vueComponentOptions)  
  parseOptions(options, vueComponentOptions)  
  parseMethods(methods, vueComponentOptions)  
  parseBehaviors(behaviors, vueComponentOptions)  
  parseLifetimes(lifetimes, vueComponentOptions)  
  parseObservers(observers, vueComponentOptions)  
  parseRelations(relations, vueComponentOptions)  
  parseProperties(properties, vueComponentOptions)  
  parsePageLifetimes(pageLifetimes, vueComponentOptions)  
  parseExternalClasses(externalClasses, vueComponentOptions)  
  parseLifecycle(mpComponentOptions, vueComponentOptions)  
  parseDefinitionFilter(mpComponentOptions, vueComponentOptions)  
    // 返回 Vue 组件  
  return vueComponentOptions  
}

在这个过程中,需处理小程序自定义组件和 Vue组件的属性对应关系及细节差异,如小程序组件的lifetimes

小程序自定义组件 Vue/uni-app 描述
created onServiceCreated 小程序的created触发时,可以访问子组件信息,而Vuecreated访问不到,故需uni-app框架映射到其它时机(onServiceCreated)执行
attached onServiceAttached 同上
ready mounted Vue 生命周期
moved - Vue中不存在该钩子,暂不支持转换
detached destroyed Vue 生命周期
小程序的pageLifetimes(组件所在页面的生命周期)在Vue中是没有的,需要映射为uni-app封装的页面生命周期: 小程序自定义组件 uni-app 描述
ready onPageShow 页面被展示时执行
hide onPageHide 页面被隐藏时执行
resize onPageResize 页面尺寸变化时执行

Behaviors特性的实现过程,类似Component构造器,不再赘述。

数据响应

Vue和小程序都有一套数据绑定系统,但机制不同,比如在Vue体系下,数据赋值是这样的:

this.a = 1

但在小程序中,数据赋值方式则是这样的:

this.setData({  
    a:1  
}) //响应式  
this.data.a = 2 //非响应式

另外,小程序和Vue在数据的propertiesobserver等方面都存在不少差异,经过我们评估,若将小程序的数据响应用法直接映射到Vue体系下,复杂度较高且有性能压力,故uni-app在H5平台按照微信的语法规范,单独实现了一套数据响应系统。

// 小程序的setData在H5平台的实现  
function setData (data, callback) {  
  if (!isPlainObject(data)) {  
    return  
  }  
  Object.keys(data).forEach(key => {  
    if (setDataByExprPath(key, data[key], this.data)) {  
      !hasOwn(this, key) && proxy(this, SOURCE_KEY, key);  
    }  
  });  
  this.$forceUpdate();//数据变化,强制视图更新(响应式)  
  isFn(callback) && this.$nextTick(callback);  
}

setData挂载到 vm 对象上,可通过this.setData这种小程序的方式调用;同时将数据绑定到data属性上,支持this.data.xx的访问方式。

export function initState (vm) {  
  const instanceData = JSON.parse(JSON.stringify(vm.$options.mpOptions.data || {}))  
  vm[SOURCE_KEY] = instanceData  

  //vm对象上挂载 setData 方法,实现小程序方法  
    vm.setData = setData   

  const propertyDefinition = {  
    get () {  
      return vm[SOURCE_KEY]  
    },  
    set (value) {  
      vm[SOURCE_KEY] = value  
    }  
  }  
    //小程序用法,可通过this.data.xx访问  
  Object.defineProperties(vm, {  
    data: propertyDefinition,  
    properties: propertyDefinition  
  })  

  Object.keys(instanceData).forEach(key => {  
    proxy(vm, SOURCE_KEY, key)  
  })  
}

虽然数据响应是uni-app自己实现的,但渲染依然使用了Vue框架的render函数,此时需小程序规范中的this.data.xx和Vue规范中的this.xx保持一致,通过代理的方式实现:

// mp/polyfill/state/proxy.js  
const sharedPropertyDefinition = {  
  enumerable: true,  
  configurable: true  
};  

function proxy (target, sourceKey, key) {  
  sharedPropertyDefinition.get = function proxyGetter () {  
    return this[sourceKey][key]  
  };  
  sharedPropertyDefinition.set = function proxySetter (val) {  
    this[sourceKey][key] = val;  
  };  
  Object.defineProperty(target, key, sharedPropertyDefinition);  
}

这里仅列出了主要的几步,中间涉及细节很多;部分无法通过Vue扩展机制实现的功能,只好修改Vue.js的内核源码,比如updateProperties支持、小程序wxsexternalClasses等功能在H5平台的支持,都需要定制部分 Vue.js runtime 源码。

结语

本文分享了uni-app将微信小程序自定义组件发行到H5平台的实现思路,希望对大家有所启发。

但这种方案,归根到底是为了解决多套项目并存时的业务重复开发的问题。

如果你是从头开发,我们建议直接选择业内成熟的跨端框架,既可以保持一套代码,更省力的维护,还可以借助框架的成熟生态(如跨端UI库插件市场),基于成熟轮子,快速完成业务的上线开发;

uni-app框架代码,包括小程序组件发行到H5平台的代码,全部开源在github,如果大家对本文逻辑有疑问,欢迎提交issue交流。

继续阅读 »

引言

移动互联网的初期,囿于设备硬件性能限制,流量以原生App为主,iOS、Android是当时两大平台。

随着硬件及OS的更新换代,H5可承载的体验逐步完善,为提高开发效率、节约资源(复用代码)以及热更新等目的,Hybrid模式成为主流;以及轻应用、服务号等平台的助推,H5网页流量暴涨,成为第三大平台。

2017年1月9日,微信发布小程序,历经3年发展,在今年主题为”未完成 Always Beta“的微信公开课 PRO上,微信团队披露,2019年小程序日活跃用户超过 3 亿,全年累计成交额达8000亿,同比增长超160%。

看到小程序如此惊人的增长力,我们有理由相信,有中国特色的小程序互联网时代已经到来,微信小程序也已成为继iOS、Android、H5之后的第四大流量平台。

平台分裂,为不同平台编写相同的业务代码,是件无趣的事情。

有追求的程序员,一直在探索代码复用的方案,Hybrid App即是代表。

而在如今的小程序时代,对于同样基于WEB技术的H5和小程序,如何实现代码复用,是很多前端工程师探索的方向。业内也已有不少成熟方案,从场景上来说,大致分为三类:

  1. 基于跨端框架,从头开发,一套代码,发行多个平台,比如DCloud出品的uni-app、京东凹凸实验室的taro
  2. 复用H5代码,转换H5代码在小程序环境中执行;适用于有H5平台沉淀,未开发小程序或小程序完善度较低的开发者;
    • 美团的mpvue框架是早期探索解决这个问题的代表,但因小程序不支持dom操作,故mpvue适用于vue的无dom操作的H5代码转换;
  • 最近微信官方推出的kbone,也是为了解决“把 Web 端的代码挪到小程序环境内执行”;不过,kbone 相比 mpvue 前进了一步(当然也有了新的性能缺陷),因为:

    kbone实现了一个适配器,在适配层里模拟出了浏览器环境,让 Web 端的代码可以不做什么改动便可运行在小程序里。

    1. 复用小程序代码,转换小程序代码在web环境中运行;适用于有小程序代码沉淀,未开发H5或H5平台完善度较低的开发者;这个方向业内成熟的方案还比较少。

uni-app近期支持了小程序自定义组件运行到H5平台,是对如上第三种场景的一种探索。

需求场景

鉴于小程序的低成本获客特征,很多厂商选择先开发小程序,验证业务模式后,再扩展至H5、App等其它平台。

开发者虽可借助转换器将小程序代码转换为uni-app项目(或其它跨端框架项目),快速实现多平台发行;但不少开发者是不敢轻易决策将跨端版本替换之前线上的小程序版本的,毕竟线上版本已稳定运行了一段时间。

常选的方案是:让原生小程序版本和uni-app跨端版本并行一段时间,微信平台继续使用原生版本,其它平台使用uni-app跨端版本;经过一段时间验证uni-app版本稳定后,再使用uni-app版替换掉原生小程序版本。

在这段并行的时间内,开发者需要同时维护微信原生、uni-app两个版本,新增业务需编写两份逻辑相同的代码,重复劳动,成本叠加,如何改善?

借助uni-app 支持将微信小程序组件运行到H5平台的特性,我们给出一种思路:

  • 开发者在原生小程序项目中,将新增业务以自定义组件的方式开发,优先上线小程序;
  • 拷贝小程序组件的wxml/wxss/js/json文件到uni-app 项目下,通过uni-app的编译器及运行时,保证小程序自定义组件在H5平台的正确运行。

这个方案的好处是:

  • 优先小程序开发,毕竟小程序早已上线,有存量用户

  • 复用小程序组件,新增业务仅需开发一套代码即可,降低开发成本

不止自己开发的小程序组件,业内开源的三方小程序组件,均可复制到uni-app项目项目中,运行到H5平台。

另外,部分公司的产品经理,会要求不同平台有不同的交互,但核心业务逻辑是相同的,开发者常会通过维护不同项目的方式来满足产品经理需求。此时,采取如上方案,同样可满足多个项目复用相同业务逻辑的诉求。

实际上,uni-app之前已支持将小程序自定义组件运行到App平台,对于有小程序组件沉淀或优先小程序的开发者来说,这是个好消息,一套业务组件,快速运行到iOS、Android、H5、微信小程序这四大流量平台(实际上也可运行到QQ小程序平台)。

uni-app 引用小程序组件演示

uni-app项目中使用自定义组件的方法很简单,分为三步:

1、拷贝小程序自定义组件到uni-app项目根目录下的wxcomponents文件夹下

2、在 pages.json 对应页面的 style -> usingComponents引入组件,如:

{  
    "pages": [  
        {  
            "path": "index/index",  
            "style": {  
                "usingComponents": {  
                     "custom": "/wxcomponents/custom/index"  
                }  
            }  
        }  
    ]  
}

3、在页面中使用自定义组件,如:

<!-- 页面模板 (index.vue) -->  
<view>  
    <!-- 在页面中对自定义组件进行引用 -->  
    <custom name="uni-app"></custom>  
</view>

方案实现思路

简单介绍下uni-app的多端发行原理。

uni-app基于Vue.js runtime,页面文件遵循Vue.js 单文件组件 (SFC) 规范,天然对H5的支持比较好,发行到H5平台时,先通过vue-loader解析.vue文件,导出Vue.js 组件选项对象,然后在运行时补充规范实现:

  • 组件:框架提供内置组件(view/swiper/picker等)的实现,保证平台UI及交互的一致性
  • 接口:在H5平台封装框架接口,比如路由跳转,showToast等界面交互
  • 生命周期:Vue.js的理念是一切皆为组件,没有应用和页面的概念;框架需创造出应用及页面的概念,模拟onLaunch、onShow等钩子

uni-app发行到小程序平台时,逻辑又有不同,主要工作有2块:

  • 编译器:将.vue文件拆分成wxml/wxss/js/json4个原生页面文件
  • 运行时:Vue.js和小程序都是逻辑视图层框架,都有数据绑定功能;运行时会实现Vue.js到小程序的数据同步,及小程序到Vue.js的事件代理

小程序自定义组件类似小程序原生的页面开发,一个自定义组件同样由wxml/wxss/js/json 4个文件组成,另有单独的组件规范(如Component 构造器、Behaviors特性等)。

所以,小程序自定义组件运行到H5平台,可借助uni-app已有平台功能快速实现:

  • 编译阶段:将wxml/wxss/js/json4个文件合并为.vue文件(类似 uni-app 发行到小程序的逆过程),然后调用uni-app发行H5平台的编译过程,通过vue-loader解析.vue文件,导出 Vue.js 组件选项对象
  • 运行阶段:实现 Component 构造器、Behaviors特性,模拟自定义组件特有的生命周期

编译:转换文件(mp2vue)

小程序自定义组件发行到H5平台,在编译环节主要有2项工作:

  1. 将自定义组件的wxml/wxss/js/json 4个文件组成,编译转换成.vue文件,即小程序转vue,可简写为mp2vue

  2. 通过vue-loader解析.vue文件,导出 Vue.js 组件选项对象

其中,步骤2是Vue.js项目的标准编译过程,略过不提;我们重点阐述步骤1。

mp2vue将4个独立wxml/wxss/js/json 的文件合并成一个.vue文件,并组装成templatescriptstyle 这种三段式的结构,流程包括:

  1. wxml文件生成template节点,同时完成指令、事件等模板语法转换
  2. js/json文件生成script节点,同时完成组件注册过
  3. wxss文件生成style节点,自动转换部分css兼容语法
  4. 合并为.vue文件

具体实现上,uni-app编译前先扫描wxcomponents目录,若存在则认为有小程序自定义组件,启动文件转换工作(uni-migration插件来完成):

//加载转换器  
const migrate = require('@dcloudio/uni-migration')   
//扫描wxcomponents目录  
const wxcomponents = path.resolve(process.env.UNI_INPUT_DIR, 'wxcomponents')   
if (fs.existsSync(wxcomponents)) {   
  migrate(wxcomponents, false, {  
    silent: true   
  }) // 转换 mp-weixin 小程序组件  
}

接着开始对wxml/wxss/js/json文件逐个解析,并合并为一个.vue文件:

module.exports = function transformFile(input, options) {  
    //首先转换json文件,判断是否为组件  
  const [jsCode, isComponent] = transformJsonFile(filepath + '.json', deps)  
  options.isComponent = isComponent  
    //转换 wxml 文件  
  const [templateCode, wxsCode = '', wxsFiles = []] = transformTemplateFile(filepath + templateExtname, options)  
    //转换wxss文件  
  const styleCode = transformStyleFile(filepath + styleExtname, options, deps) || ''  
  //转换js文件  
  const scriptCode = transformScriptFile(filepath + '.js', jsCode, options, deps)  
    // 生成合并后的.vue文件源码  
  return [  
    `${commentsCode}<template>  
${templateCode}  
</template>  
${wxsCode}  
<script>  
${scriptCode}  
</script>  
<style platform="mp-weixin">  
${styleCode}  
</style>`,  
    deps,  
    wxsFiles  
  ]  
}

进一步细节说明,wxml文件转为template节点时,需完成各项指令、事件等模板语法的转换,例如:

小程序自定义组件 Vue组件 描述
wx:if v-if 条件渲染
wx:for v-for 列表渲染
bindtap @click 元素点击事件

将一个最简自定义组件,按照如上流程转换,结果示意如下:

运行时:模拟小程序组件环境

uni-app的编译器并不转换小程序组件的 JS 代码,依然保留Component构造器的写法,甚至其中的API依然是wx.开头的方式,这些都依赖uni-app在H5平台的运行时来解决,主要有如下几部分内容:

  • Component构造器:解析小程序组件的各种选项配置,转换为Vue组件定义,包括变通实现其中的差异部分,如小程序组件特有的”组件所在页面的生命周期“
  • Behaviors特性:转换为Vue的混入(mixin)
  • 数据响应:在H5平台实现setData接口及this.data.xx = yy的数据通讯机制
  • API前缀:可在运行时通过代理机制,自动将wx.xx替换为uni.xx,这个比较简单,不详述

Component构造器

uni-app在H5平台定义了一个Component函数,执行到小程序的Component构造器函数后,开始循环解析其属性,并转换成Vue组件属性,流程示意代码如下:

export function Component (options) {  
  const componentOptions = parseComponent(options)  
  componentOptions.mixins.unshift(polyfill)  
  componentOptions.mpOptions.path = global['__wxRoute']  
  initRelationsHandler(componentOptions)  
  global['__wxComponents'][global['__wxRoute']] = componentOptions  
}  

export function parseComponent (mpComponentOptions) {  
  const {  
    data,  
    options,  
    methods,  
    behaviors,  
    lifetimes,  
    observers,  
    relations,  
    properties,  
    pageLifetimes,  
    externalClasses  
  } = mpComponentOptions  

  const vueComponentOptions = {  
    mixins: [],  
    props: {},  
    watch: {},  
    mpOptions: {  
      mpObservers: []  
    }  
  }  

    // 开始逐个解析所有属性  
  parseData(data, vueComponentOptions)  
  parseOptions(options, vueComponentOptions)  
  parseMethods(methods, vueComponentOptions)  
  parseBehaviors(behaviors, vueComponentOptions)  
  parseLifetimes(lifetimes, vueComponentOptions)  
  parseObservers(observers, vueComponentOptions)  
  parseRelations(relations, vueComponentOptions)  
  parseProperties(properties, vueComponentOptions)  
  parsePageLifetimes(pageLifetimes, vueComponentOptions)  
  parseExternalClasses(externalClasses, vueComponentOptions)  
  parseLifecycle(mpComponentOptions, vueComponentOptions)  
  parseDefinitionFilter(mpComponentOptions, vueComponentOptions)  
    // 返回 Vue 组件  
  return vueComponentOptions  
}

在这个过程中,需处理小程序自定义组件和 Vue组件的属性对应关系及细节差异,如小程序组件的lifetimes

小程序自定义组件 Vue/uni-app 描述
created onServiceCreated 小程序的created触发时,可以访问子组件信息,而Vuecreated访问不到,故需uni-app框架映射到其它时机(onServiceCreated)执行
attached onServiceAttached 同上
ready mounted Vue 生命周期
moved - Vue中不存在该钩子,暂不支持转换
detached destroyed Vue 生命周期
小程序的pageLifetimes(组件所在页面的生命周期)在Vue中是没有的,需要映射为uni-app封装的页面生命周期: 小程序自定义组件 uni-app 描述
ready onPageShow 页面被展示时执行
hide onPageHide 页面被隐藏时执行
resize onPageResize 页面尺寸变化时执行

Behaviors特性的实现过程,类似Component构造器,不再赘述。

数据响应

Vue和小程序都有一套数据绑定系统,但机制不同,比如在Vue体系下,数据赋值是这样的:

this.a = 1

但在小程序中,数据赋值方式则是这样的:

this.setData({  
    a:1  
}) //响应式  
this.data.a = 2 //非响应式

另外,小程序和Vue在数据的propertiesobserver等方面都存在不少差异,经过我们评估,若将小程序的数据响应用法直接映射到Vue体系下,复杂度较高且有性能压力,故uni-app在H5平台按照微信的语法规范,单独实现了一套数据响应系统。

// 小程序的setData在H5平台的实现  
function setData (data, callback) {  
  if (!isPlainObject(data)) {  
    return  
  }  
  Object.keys(data).forEach(key => {  
    if (setDataByExprPath(key, data[key], this.data)) {  
      !hasOwn(this, key) && proxy(this, SOURCE_KEY, key);  
    }  
  });  
  this.$forceUpdate();//数据变化,强制视图更新(响应式)  
  isFn(callback) && this.$nextTick(callback);  
}

setData挂载到 vm 对象上,可通过this.setData这种小程序的方式调用;同时将数据绑定到data属性上,支持this.data.xx的访问方式。

export function initState (vm) {  
  const instanceData = JSON.parse(JSON.stringify(vm.$options.mpOptions.data || {}))  
  vm[SOURCE_KEY] = instanceData  

  //vm对象上挂载 setData 方法,实现小程序方法  
    vm.setData = setData   

  const propertyDefinition = {  
    get () {  
      return vm[SOURCE_KEY]  
    },  
    set (value) {  
      vm[SOURCE_KEY] = value  
    }  
  }  
    //小程序用法,可通过this.data.xx访问  
  Object.defineProperties(vm, {  
    data: propertyDefinition,  
    properties: propertyDefinition  
  })  

  Object.keys(instanceData).forEach(key => {  
    proxy(vm, SOURCE_KEY, key)  
  })  
}

虽然数据响应是uni-app自己实现的,但渲染依然使用了Vue框架的render函数,此时需小程序规范中的this.data.xx和Vue规范中的this.xx保持一致,通过代理的方式实现:

// mp/polyfill/state/proxy.js  
const sharedPropertyDefinition = {  
  enumerable: true,  
  configurable: true  
};  

function proxy (target, sourceKey, key) {  
  sharedPropertyDefinition.get = function proxyGetter () {  
    return this[sourceKey][key]  
  };  
  sharedPropertyDefinition.set = function proxySetter (val) {  
    this[sourceKey][key] = val;  
  };  
  Object.defineProperty(target, key, sharedPropertyDefinition);  
}

这里仅列出了主要的几步,中间涉及细节很多;部分无法通过Vue扩展机制实现的功能,只好修改Vue.js的内核源码,比如updateProperties支持、小程序wxsexternalClasses等功能在H5平台的支持,都需要定制部分 Vue.js runtime 源码。

结语

本文分享了uni-app将微信小程序自定义组件发行到H5平台的实现思路,希望对大家有所启发。

但这种方案,归根到底是为了解决多套项目并存时的业务重复开发的问题。

如果你是从头开发,我们建议直接选择业内成熟的跨端框架,既可以保持一套代码,更省力的维护,还可以借助框架的成熟生态(如跨端UI库插件市场),基于成熟轮子,快速完成业务的上线开发;

uni-app框架代码,包括小程序组件发行到H5平台的代码,全部开源在github,如果大家对本文逻辑有疑问,欢迎提交issue交流。

收起阅读 »

关于v3下一些子组件样式出现问题

v3 css

其实样式出现问题基本上是有地方给了样式,为什么v3下有一些样式会乱掉呢,那是因为和其它库里面的一下样式class类名重复了,这时候修改你的class名称就可以了,为什么v2不会,v3会这样子,具体问官方吧

其实样式出现问题基本上是有地方给了样式,为什么v3下有一些样式会乱掉呢,那是因为和其它库里面的一下样式class类名重复了,这时候修改你的class名称就可以了,为什么v2不会,v3会这样子,具体问官方吧