HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

hbuilder的win版和mac版sass编译报错,一直报错,ruby已经安装

hbuilder的win版和mac版sass编译报错,一直报错,ruby已经安装
不知道为什么报这个错,tab是4个空格

hbuilder的win版和mac版sass编译报错,一直报错,ruby已经安装
不知道为什么报这个错,tab是4个空格

Hotfix只需几分钟让您的应用拥有热更新能力

js

快速使用 项目地址

安装

npm 安装

npm i h5plus-hotfix -S

script加载

<script src="hotfix-bs.js"></script>

使用

hotfix({  
  url: updateUrl,  
  before(data) {  
    // 确认安装  
    return new Promise(resolve => {  
      plus.nativeUI.confirm(data.title, (selected) => {  
        if (selected.index === 0) {  
          plus.nativeUI.showWaiting("下载更新文件...");  
          resolve(data);  
        }  
      }, {  
          title: data.description,  
          buttons: ["确认更新", "取消"],  
          verticalAlign: "bottom"  
        });  
    });  
  },  
  success() {  
    console.log('安装成功')  
    plus.runtime.restart(); // 重启app   
    plus.nativeUI.closeWaiting();  
  },  
  error(e) {  
    // 错误显示  
    plus.nativeUI.closeWaiting();  
    console.log("安装wgt文件失败[" + e.code + "]:" + e.message);  
    plus.nativeUI.alert("安装wgt文件失败[" + e.code + "]:" + e.message);  
  },  
  onProgress(p) {  
    console.log(p) // 下载进度  
  }  
});
继续阅读 »

快速使用 项目地址

安装

npm 安装

npm i h5plus-hotfix -S

script加载

<script src="hotfix-bs.js"></script>

使用

hotfix({  
  url: updateUrl,  
  before(data) {  
    // 确认安装  
    return new Promise(resolve => {  
      plus.nativeUI.confirm(data.title, (selected) => {  
        if (selected.index === 0) {  
          plus.nativeUI.showWaiting("下载更新文件...");  
          resolve(data);  
        }  
      }, {  
          title: data.description,  
          buttons: ["确认更新", "取消"],  
          verticalAlign: "bottom"  
        });  
    });  
  },  
  success() {  
    console.log('安装成功')  
    plus.runtime.restart(); // 重启app   
    plus.nativeUI.closeWaiting();  
  },  
  error(e) {  
    // 错误显示  
    plus.nativeUI.closeWaiting();  
    console.log("安装wgt文件失败[" + e.code + "]:" + e.message);  
    plus.nativeUI.alert("安装wgt文件失败[" + e.code + "]:" + e.message);  
  },  
  onProgress(p) {  
    console.log(p) // 下载进度  
  }  
});
收起阅读 »

uni-app 二维码生成器分享

uni_app 分享 二维码 uniapp插件

看到很多人在问,就分享一个吧

// 引入二维码库  
import QR from "../../utils/wxqrcode.js" // 二维码生成器  

let img = QR.createQrCodeImg('生成的内容', {  
     size: parseInt(300)//二维码大小  
})

调用后会生成 base64 格式的图片,直接复制变量就可以用啦。

PS: 新版二维码生成器在这里,解决内容大于40个字报错的问题
点我查看新版

继续阅读 »

看到很多人在问,就分享一个吧

// 引入二维码库  
import QR from "../../utils/wxqrcode.js" // 二维码生成器  

let img = QR.createQrCodeImg('生成的内容', {  
     size: parseInt(300)//二维码大小  
})

调用后会生成 base64 格式的图片,直接复制变量就可以用啦。

PS: 新版二维码生成器在这里,解决内容大于40个字报错的问题
点我查看新版

收起阅读 »

HBuilderX被误报病毒木马的说明

病毒 木马

本帖文档已集成到: hx产品文档

首先说明,HBuilderX每次发正式版都会经过专业安全公司的单独检测。
通过后才会正式更新。请放心使用。
Alpha版可能不会发安全公司检测,但这只是形式。几年来,安全公司从未检测出一个病毒木马。但不给他们提交检测,他们就会乱报警告。

下图为360检测通过页面截图

下图为微软检测通过页面截图

还有几点注意:
1、为什么通过检测,有时我本机的微软杀毒软件仍然报警
360通过检测后一般实时更新,但微软的病毒定义库升级走的是windows update统一的机制,并且有一套自己的缓存机制。
在Windows Defender团队回复的内容中可知(见上图紫色方框),需要用管理员身份运行命令行工具,执行命令才能清除缓存。
微软的回复是英文,我们翻译一下方便大家理解:

> 感谢您提交检测。
> 我们已审核了该文件,并已删除了检测结果。(之前的检测结果为有木马,在我们提交后微软回复删除了之前的结果,就是无毒的意思)
> 请尝试以下步骤清除缓存的检测并获取最新的恶意软件定义。
> 1.以管理员身份打开命令提示符,将目录更改为c:\Program Files\Windows Defender
> 2.运行“MpCmdRun.exe -removedefinitions -dynamicsignatures”
> 最新定义可从此处下载:https://www.microsoft.com/en-us/wdsi/definitions
> 最好的祝福,
> Windows Defender 回复

另外红框中的"Not malware",中文译为"并非恶意软件"。

2、单独认证和推测算法的区别
除了360和微软,可能还有其他安全软件会误报病毒木马。这些都不用理睬,直接给HBuilderX加白名单。
原因如下:
各家安全软件,都是有一个推测算法,觉得有可能有病毒就会报,但经常误报。
不管是360还是windows defender都经常误报,比如:https://www.cnbeta.com/articles/tech/758679.htm
若软件开发者把软件单独提交给安全平台检测认证,此时走的不是推测算法,而是专业的、针对该软件的安全测试,在安全平台检测通过后会加白。
HBuilderX在未被360单独认证通过前,360一样报警。但认证通过后,360定义库自动更新,软件什么都不变,也不再被报警。
单独认证是一个严谨的、单独的、针对性的检测,不是推测算法,单独认证通过后就是真的没有病毒木马。
目前国外的一些安全软件,包括微软、赛门铁克,并没有通畅的国内软件提交认证通道。
但这些安全软件的推测算法并不准,所以对HBuilderX经常误报。
因为360提交方便、认证快,所以DCloud一般是等360单独认证通过后就会更新版本。
在360单独认证HBuilderX无毒通过后,其他靠推测算法报警的安全软件的警告不用理睬。
各家安全软件都有扫描或信任白名单,把HBuilderX的目录设为信任目录即可。

继续阅读 »

本帖文档已集成到: hx产品文档

首先说明,HBuilderX每次发正式版都会经过专业安全公司的单独检测。
通过后才会正式更新。请放心使用。
Alpha版可能不会发安全公司检测,但这只是形式。几年来,安全公司从未检测出一个病毒木马。但不给他们提交检测,他们就会乱报警告。

下图为360检测通过页面截图

下图为微软检测通过页面截图

还有几点注意:
1、为什么通过检测,有时我本机的微软杀毒软件仍然报警
360通过检测后一般实时更新,但微软的病毒定义库升级走的是windows update统一的机制,并且有一套自己的缓存机制。
在Windows Defender团队回复的内容中可知(见上图紫色方框),需要用管理员身份运行命令行工具,执行命令才能清除缓存。
微软的回复是英文,我们翻译一下方便大家理解:

> 感谢您提交检测。
> 我们已审核了该文件,并已删除了检测结果。(之前的检测结果为有木马,在我们提交后微软回复删除了之前的结果,就是无毒的意思)
> 请尝试以下步骤清除缓存的检测并获取最新的恶意软件定义。
> 1.以管理员身份打开命令提示符,将目录更改为c:\Program Files\Windows Defender
> 2.运行“MpCmdRun.exe -removedefinitions -dynamicsignatures”
> 最新定义可从此处下载:https://www.microsoft.com/en-us/wdsi/definitions
> 最好的祝福,
> Windows Defender 回复

另外红框中的"Not malware",中文译为"并非恶意软件"。

2、单独认证和推测算法的区别
除了360和微软,可能还有其他安全软件会误报病毒木马。这些都不用理睬,直接给HBuilderX加白名单。
原因如下:
各家安全软件,都是有一个推测算法,觉得有可能有病毒就会报,但经常误报。
不管是360还是windows defender都经常误报,比如:https://www.cnbeta.com/articles/tech/758679.htm
若软件开发者把软件单独提交给安全平台检测认证,此时走的不是推测算法,而是专业的、针对该软件的安全测试,在安全平台检测通过后会加白。
HBuilderX在未被360单独认证通过前,360一样报警。但认证通过后,360定义库自动更新,软件什么都不变,也不再被报警。
单独认证是一个严谨的、单独的、针对性的检测,不是推测算法,单独认证通过后就是真的没有病毒木马。
目前国外的一些安全软件,包括微软、赛门铁克,并没有通畅的国内软件提交认证通道。
但这些安全软件的推测算法并不准,所以对HBuilderX经常误报。
因为360提交方便、认证快,所以DCloud一般是等360单独认证通过后就会更新版本。
在360单独认证HBuilderX无毒通过后,其他靠推测算法报警的安全软件的警告不用理睬。
各家安全软件都有扫描或信任白名单,把HBuilderX的目录设为信任目录即可。

收起阅读 »

企业为什么要选郑州小程序开发,原因在这

微信小程序

  从小程序发布到现在郑州小程序开发随处可见,可以看出小程序具备了很多的投资优势,而小程序依托着活跃度超高的微信平台,它的未来备受瞩目。那么,微信小程序开发到底有哪些优点可以有这么高的关注度呢,对于这样的问题,接下来就为大家分析解答一下。

  1、app角度

  很多人把app和小程序做比较,其实小程序对app有好处也有坏处。相对于很高频的app,小程序并没有实质性的威胁;对于比较低频的app来说,小程序反而会帮产品积累“人气”,增加营销机会;而对于一些既不高频也不低频的app来说,就需要格外注意了。如果稍不注意,就会被取而代之。

  2、用户角度

  满足了低频服务类产品的需求,需要用到的时候,打开小程序,用完就关掉,不想用,还可以删除,用完就走。比如,不常出门的人,需要订酒店或定火车票就可以打开小程序,用时再打开,避免app一直保存在手机里占用内存,特殊场景下的个性化需求,我们经常会遇到都是同一类型的app,却要下载好几个,这种情况下,小程序就可以完美解决。

  3、线下商家角度

  深圳拓略认为对于商家来说,小程序所带来的客流量就很大了,用户可以通过微信搜索附近的店找到附近的小程序。对线下商家来说,小程序的价值主要体现在“O2O服务小程序”,“公众号+小程序”,“工具类小程序”,“生活服务类小程序”。

  “一些放在桌面累赘,又不能没有的app终于有归宿了”,这是对于微信小程序给用户带来的价值的主要论调。它的特点是小而快,它的目的主要是解决小应用的问题,重点在于灵活快捷,用完就走,这也是目前企业选择投资开发小程序的原因所在。本文由专业的郑州小程序开发燚轩科技整理发布。

继续阅读 »

  从小程序发布到现在郑州小程序开发随处可见,可以看出小程序具备了很多的投资优势,而小程序依托着活跃度超高的微信平台,它的未来备受瞩目。那么,微信小程序开发到底有哪些优点可以有这么高的关注度呢,对于这样的问题,接下来就为大家分析解答一下。

  1、app角度

  很多人把app和小程序做比较,其实小程序对app有好处也有坏处。相对于很高频的app,小程序并没有实质性的威胁;对于比较低频的app来说,小程序反而会帮产品积累“人气”,增加营销机会;而对于一些既不高频也不低频的app来说,就需要格外注意了。如果稍不注意,就会被取而代之。

  2、用户角度

  满足了低频服务类产品的需求,需要用到的时候,打开小程序,用完就关掉,不想用,还可以删除,用完就走。比如,不常出门的人,需要订酒店或定火车票就可以打开小程序,用时再打开,避免app一直保存在手机里占用内存,特殊场景下的个性化需求,我们经常会遇到都是同一类型的app,却要下载好几个,这种情况下,小程序就可以完美解决。

  3、线下商家角度

  深圳拓略认为对于商家来说,小程序所带来的客流量就很大了,用户可以通过微信搜索附近的店找到附近的小程序。对线下商家来说,小程序的价值主要体现在“O2O服务小程序”,“公众号+小程序”,“工具类小程序”,“生活服务类小程序”。

  “一些放在桌面累赘,又不能没有的app终于有归宿了”,这是对于微信小程序给用户带来的价值的主要论调。它的特点是小而快,它的目的主要是解决小应用的问题,重点在于灵活快捷,用完就走,这也是目前企业选择投资开发小程序的原因所在。本文由专业的郑州小程序开发燚轩科技整理发布。

收起阅读 »

郑州app开发报价都和哪些方面有关呢

5 App开发

  开发一款app软件要多少钱呢?这是在郑州app开发公司制作app的过程中,客户首先关注的问题了。一般在开发app之前,客户都会先咨询关于“app开发要多少钱”的问题。那么开发一款手机应用软件app到底需要多少钱呢?今天就来跟大家讨论一下这个问题吧。

  1、看app应用客户端的质量要求

  一样的app,质量不同价格肯定也受影响,并且app还有一个升级的问题,这个升级是有大量工作要做的,是否承担升级和完善的责任也会影响价格;

  2、app软件的本身功能的复杂度

  功能是一个app开发的核心,一般的app有复杂功能和简单的功能,比如商城类的app功能相对来说比较复杂,而简单的企业产品展示类app开发的功能就比较简单了。还需要看服务器后台支持的复杂度的难易程度。

  3、app开发工作范围

  如果你已做好设计,并制作好界面素材,准备好数据,并自备帐号自己完成上线申请,仅委托开发就要便宜一些,反之如果委托全新的创意加上功能的策划,费用就会增高不少。

  一般开发一款应用软件的价钱会在几万到几十万不等,至于具体的影响到开发一个app价格的因素,最终还是该app开发功能需求的复杂程度来决定的。信息来源郑州app开发公司,如需转载,请注明出处。

继续阅读 »

  开发一款app软件要多少钱呢?这是在郑州app开发公司制作app的过程中,客户首先关注的问题了。一般在开发app之前,客户都会先咨询关于“app开发要多少钱”的问题。那么开发一款手机应用软件app到底需要多少钱呢?今天就来跟大家讨论一下这个问题吧。

  1、看app应用客户端的质量要求

  一样的app,质量不同价格肯定也受影响,并且app还有一个升级的问题,这个升级是有大量工作要做的,是否承担升级和完善的责任也会影响价格;

  2、app软件的本身功能的复杂度

  功能是一个app开发的核心,一般的app有复杂功能和简单的功能,比如商城类的app功能相对来说比较复杂,而简单的企业产品展示类app开发的功能就比较简单了。还需要看服务器后台支持的复杂度的难易程度。

  3、app开发工作范围

  如果你已做好设计,并制作好界面素材,准备好数据,并自备帐号自己完成上线申请,仅委托开发就要便宜一些,反之如果委托全新的创意加上功能的策划,费用就会增高不少。

  一般开发一款应用软件的价钱会在几万到几十万不等,至于具体的影响到开发一个app价格的因素,最终还是该app开发功能需求的复杂程度来决定的。信息来源郑州app开发公司,如需转载,请注明出处。

收起阅读 »

使用 Hbuilder自定义注释代码块

类似于Eclipse里面那种的快速方法注释的功能我在Hbuilder中并没有找到,但是HB提供了自定义各种类型文件代码块的功能,我们可以利用这一功能来自定义注释,之前用了很久,但是后来重装系统就麻烦了半天给重写了一遍,这次就放在这里,以便日后查阅
工具 -> 扩展代码块 -> 自定义PHP代码块

  #个人自定义代码块  
  snippet "/*多行注释*/" do |s|  
    today = Time.new  
    now = today.strftime("%Y年%m月%d日")  
    s.trigger = 'zhushi'  
    s.expansion = "/**  
 * ${1:方法名}   
 * ${2: }  
 * @param ${3: }  
 * @return $0  
 * @version 1.0  
 * @author 您的大名 #{now}  
 * */"  
  end

这个日期嘛,是有问题的,按照phpDoc来说应该是没有这个属性的,但是我们项目中经常会遇到一个方法时常更新的情况,这时候后期维护就有必要填这个日期的,这里的问题就是:写完后日期固定了。。。如果想每天都更新的话,就需要每次都打开这个文件,修改下然后再保存,我想应该是做了缓存所以不能动态实时更新时间的。虽然麻烦了点,不过一点点一次就当签到得了。不需要日期的删掉它就可以了

继续阅读 »

类似于Eclipse里面那种的快速方法注释的功能我在Hbuilder中并没有找到,但是HB提供了自定义各种类型文件代码块的功能,我们可以利用这一功能来自定义注释,之前用了很久,但是后来重装系统就麻烦了半天给重写了一遍,这次就放在这里,以便日后查阅
工具 -> 扩展代码块 -> 自定义PHP代码块

  #个人自定义代码块  
  snippet "/*多行注释*/" do |s|  
    today = Time.new  
    now = today.strftime("%Y年%m月%d日")  
    s.trigger = 'zhushi'  
    s.expansion = "/**  
 * ${1:方法名}   
 * ${2: }  
 * @param ${3: }  
 * @return $0  
 * @version 1.0  
 * @author 您的大名 #{now}  
 * */"  
  end

这个日期嘛,是有问题的,按照phpDoc来说应该是没有这个属性的,但是我们项目中经常会遇到一个方法时常更新的情况,这时候后期维护就有必要填这个日期的,这里的问题就是:写完后日期固定了。。。如果想每天都更新的话,就需要每次都打开这个文件,修改下然后再保存,我想应该是做了缓存所以不能动态实时更新时间的。虽然麻烦了点,不过一点点一次就当签到得了。不需要日期的删掉它就可以了

收起阅读 »

基于 MUI 构建一个具有 90 +页面的APP应用,欢迎star

mui

前言

mui是一款接近原生App体验的前端框架,只需要掌握前端技术就可以开发APP应用,官方有提供功能比较全面的demo版本,
但在实战中总会遇到一些不可避免但坑,对于没有接触过mui的开发者,难免会浪费很多时间在踩坑上。

该项目以mui为开发框架,artTemplate.js作为js模版引擎,没有繁琐的配置和编译过程,拿来就可以上手,适合刚接触mui的同学参考和学习

项目运行

项目地址

git clone https://github.com/EasyTuan/mui-kidApp.git  

打开HBuider,打开项目

右键项目=>转换为移动App

运行=>真机运行(需要usb连接手机)

注:服务器到期,接口服务不再支持,能正常登陆和退出,不影响正常功能但预览和学习

目标功能

  • [x] 定位功能 -- 完成
  • [x] 选择城市 -- 完成
  • [x] 展示所选地址附近商家列表 -- 完成
  • [x] 在高德地图中寻找店铺 -- 完成
  • [x] 搜索文章,赛事 -- 完成
  • [x] 商家列表页 -- 完成
  • [x] 店铺评价页面 -- 完成
  • [x] 单张卡牌详情页面 -- 完成
  • [x] 商家详情页 -- 完成
  • [x] 登录、注册 -- 完成
  • [x] 三方微信、QQ登陆 -- 完成
  • [x] 修改密码 -- 完成
  • [x] 个人中心 -- 完成
  • [x] 发送短信、语音验证 -- 完成
  • [x] 赛事列表 -- 完成
  • [x] 赛事详情 -- 完成
  • [x] 添加、删除、修改收货地址 -- 完成
  • [x] 帐户信息 -- 完成
  • [x] 服务中心 -- 完成
  • [x] 红包 -- 完成
  • [x] 上传头像 -- 完成
  • [x] 卡牌对战发起 -- 完成

业务介绍

入口地址为 html/main.html

目录结构

├── css                     //css样式文件  
├── fonts                   //字体图标  
├── html                        //页面  
├── images                  //图片  
├── js                      //js  
│    └── lib                        //js第三方库  
├── unpackage               //App图标、启动页  
└── manifest.json           //App配置文件  

说明

如果对您有帮助,您可以点右上角 "Star" 支持一下 谢谢! ^_^

或者您可以 "follow" 一下,我会不断开源更多的有趣的项目

如有问题请直接在 Issues 中提,或者您发现问题并有非常好的解决方案,欢迎 PR

继续阅读 »

前言

mui是一款接近原生App体验的前端框架,只需要掌握前端技术就可以开发APP应用,官方有提供功能比较全面的demo版本,
但在实战中总会遇到一些不可避免但坑,对于没有接触过mui的开发者,难免会浪费很多时间在踩坑上。

该项目以mui为开发框架,artTemplate.js作为js模版引擎,没有繁琐的配置和编译过程,拿来就可以上手,适合刚接触mui的同学参考和学习

项目运行

项目地址

git clone https://github.com/EasyTuan/mui-kidApp.git  

打开HBuider,打开项目

右键项目=>转换为移动App

运行=>真机运行(需要usb连接手机)

注:服务器到期,接口服务不再支持,能正常登陆和退出,不影响正常功能但预览和学习

目标功能

  • [x] 定位功能 -- 完成
  • [x] 选择城市 -- 完成
  • [x] 展示所选地址附近商家列表 -- 完成
  • [x] 在高德地图中寻找店铺 -- 完成
  • [x] 搜索文章,赛事 -- 完成
  • [x] 商家列表页 -- 完成
  • [x] 店铺评价页面 -- 完成
  • [x] 单张卡牌详情页面 -- 完成
  • [x] 商家详情页 -- 完成
  • [x] 登录、注册 -- 完成
  • [x] 三方微信、QQ登陆 -- 完成
  • [x] 修改密码 -- 完成
  • [x] 个人中心 -- 完成
  • [x] 发送短信、语音验证 -- 完成
  • [x] 赛事列表 -- 完成
  • [x] 赛事详情 -- 完成
  • [x] 添加、删除、修改收货地址 -- 完成
  • [x] 帐户信息 -- 完成
  • [x] 服务中心 -- 完成
  • [x] 红包 -- 完成
  • [x] 上传头像 -- 完成
  • [x] 卡牌对战发起 -- 完成

业务介绍

入口地址为 html/main.html

目录结构

├── css                     //css样式文件  
├── fonts                   //字体图标  
├── html                        //页面  
├── images                  //图片  
├── js                      //js  
│    └── lib                        //js第三方库  
├── unpackage               //App图标、启动页  
└── manifest.json           //App配置文件  

说明

如果对您有帮助,您可以点右上角 "Star" 支持一下 谢谢! ^_^

或者您可以 "follow" 一下,我会不断开源更多的有趣的项目

如有问题请直接在 Issues 中提,或者您发现问题并有非常好的解决方案,欢迎 PR

收起阅读 »

分享 html5plus 的 native.d.ts 文件

HTML5+ Native.JS

Typescript of native.js

安装

npm install --save-dev native.d.ts

使用

import 'native.d.ts';

document.addEventListener('plusready', runApp, false);

function runApp {
// use plus.*
}

仓库地址

Github : https://github.com/ymzuiku/native.d.ts

继续阅读 »

Typescript of native.js

安装

npm install --save-dev native.d.ts

使用

import 'native.d.ts';

document.addEventListener('plusready', runApp, false);

function runApp {
// use plus.*
}

仓库地址

Github : https://github.com/ymzuiku/native.d.ts

收起阅读 »

封装一个简单实用的 plusready 方法

HTML5+ plus is not defined plusready plus

如果有小伙伴看过 mui.js 的源码的话,对于以下代码就不会陌生。

var plusReady = function (callback) {  
    if (window.plus) {  
        callback();  
    } else {  
        document.addEventListener('plusready', callback);  
    }  
};

这个方法,是用来确保 5+ API 扩展成功了,在这个方法的回调中调用 5+ 扩展 API,不会出现 plus is not defined 错误。

因为 Android 和 iOS 的一些机制不同,再加上不同的 ROM 和 Webview 都会对 5+ 扩展 API 的注入生效有所影响。
因此,实际应用中判定扩展完成,并不能单靠 plusready 事件。

情况一
在页面加载完成之前就已经触发了 plusready 事件,window.plus 扩展对象已经存在了。这时候,是不会重复触发 plusready 事件了。因此,在页面中是监听不到 plusready 事件了。也就有了先判定 window.plus 是否存在的逻辑。

情况二
页面加载后,扩展 API 加载完成,触发 plusready 事件。此时,是可以在页面中监听到 plusready 事件的。因此,就有了监听 plusready 事件触发的逻辑。

考虑到以上这些情况,就可以确保在这个 plusReady 的回调中,调用扩展的 window.plus 对象不会出现未定义的情况。

但是依旧有特殊的情况,那就是页面中本身引入了其它框架或者自己定义了 window.plus 对象,约定的原生能力扩展对象 window.plus 被占用了。
应当避免这种情况的发生,即便是引入其它库,也是可以修改其源码来处理的。
前面提到了,5+ 扩展 API 注入的时机是不确定的,因此如果只是单一的将已存在的 window.plus 对象重新赋值给其它变量,也会造成一定的隐患。

plusReady(function () {  
    alert(plus.runtime.appid);  
});
继续阅读 »

如果有小伙伴看过 mui.js 的源码的话,对于以下代码就不会陌生。

var plusReady = function (callback) {  
    if (window.plus) {  
        callback();  
    } else {  
        document.addEventListener('plusready', callback);  
    }  
};

这个方法,是用来确保 5+ API 扩展成功了,在这个方法的回调中调用 5+ 扩展 API,不会出现 plus is not defined 错误。

因为 Android 和 iOS 的一些机制不同,再加上不同的 ROM 和 Webview 都会对 5+ 扩展 API 的注入生效有所影响。
因此,实际应用中判定扩展完成,并不能单靠 plusready 事件。

情况一
在页面加载完成之前就已经触发了 plusready 事件,window.plus 扩展对象已经存在了。这时候,是不会重复触发 plusready 事件了。因此,在页面中是监听不到 plusready 事件了。也就有了先判定 window.plus 是否存在的逻辑。

情况二
页面加载后,扩展 API 加载完成,触发 plusready 事件。此时,是可以在页面中监听到 plusready 事件的。因此,就有了监听 plusready 事件触发的逻辑。

考虑到以上这些情况,就可以确保在这个 plusReady 的回调中,调用扩展的 window.plus 对象不会出现未定义的情况。

但是依旧有特殊的情况,那就是页面中本身引入了其它框架或者自己定义了 window.plus 对象,约定的原生能力扩展对象 window.plus 被占用了。
应当避免这种情况的发生,即便是引入其它库,也是可以修改其源码来处理的。
前面提到了,5+ 扩展 API 注入的时机是不确定的,因此如果只是单一的将已存在的 window.plus 对象重新赋值给其它变量,也会造成一定的隐患。

plusReady(function () {  
    alert(plus.runtime.appid);  
});
收起阅读 »

uni-app导航栏开发指南

导航栏 uniapp

看示例,这里的功能比文档里写的多:https://ext.dcloud.net.cn/plugin?id=1765

本文虽长,但值得看完。可避免开发中的很多坑

uni-app 自带原生导航栏,在pages.json里配置。
原生导航的体验更好,渲染新页面时,原生导航栏的渲染无需等待新页面dom加载,可以在新页面进入动画开始时就渲染。

原生导航还可以避免滚动条通顶,并方便的控制原生下拉刷新。
通过pages.json的配置,可以简单的、跨端的、高性能的开发业务。

但原生导航栏的扩展能力有限的。尤其是微信下,没有提供太多导航栏的配置。
在App下,pages.json里每个页面的app-plus下可以设置titleNView等更多参数,可以得到比微信小程序更丰富的扩展性。
另外,开发者也可以在必要时取消原生导航栏,使用view自行绘制导航栏。

原生导航栏的通用配置

原生导航栏的配置,均在pages.json里,每个page下面的style配置中的navigationBar各个参数配置,即为通用配置,小程序、app、h5均生效。参考https://uniapp.dcloud.io/collocation/pages?id=style

全局取消原生导航栏

在pages.json的globalStyle里,有个navigationStyle设置,默认是default,即带有原生导航栏。
也可以设置为custom。
在设为custom后,所有页面都没有原生导航。
但在微信小程序里,右上角始终都有一个胶囊按钮。
很多微信小游戏界面上也没原生导航栏,但有胶囊按钮。
一般App里不会使用这个参数配置。建议个别页面单独设置不使用原生导航,具体见下。

单独去除原生导航栏

支持通过如下方法取消单独一个页面的原生导航栏。但小程序右上角胶囊按钮仍然去不掉。页面配置 navigationStyle 为 custom:

{  
    "path" : "pages/log/log",  
    "style" : {  
        "navigationStyle":"custom"  
    }  
}

原生导航栏在App侧的扩展

微信小程序的设计里,没有给原生导航提供太多自定义能力。在开发App时是不够用的。
pages.json里,每个page下面的style下面还有一个子扩展节点:app-plus。
这个节点定义了在5+App环境下,也即iOS、Android环境下,增强的配置。
其中有一个子节点titleNView,这个是5+规范里webview页面的原生导航窗体规范。
参考https://uniapp.dcloud.io/collocation/pages?id=app-plus

App去除导航栏后改变状态栏样式

App因为默认为沉浸式,去除导航栏后,页面顶部会直通到状态栏的区域,可能出现如下需求:

  • 改变状态栏文字颜色:设置该页面的 navigationBarTextStyle 属性,可取值为 black/white。如果想单独设置颜色,App端可使用plus.navigator.setStatusBarStyle设置。部分低端Android手机(4.4)自身不支持设置状态栏前景色。
  • 改变状态栏背景颜色:通过绘制一个占位的view固定放在状态栏位置,设置此view的背景颜色,即可达到想要的效果,uni-app提供了一个状态栏高度的css变量,具体参考:http://uniapp.dcloud.io/frame?id=css%E5%8F%98%E9%87%8F

以下为示例:

<!-- #ifdef APP-PLUS -->  
<view class="status_bar">  
    <view class="top_view"></view>  
</view>  
<!-- #endif -->
.status_bar {  
    height: var(--status-bar-height);  
    width: 100%;  
    background-color: #F8F8F8;  
}  
.top_view {  
    height: var(--status-bar-height);  
    width: 100%;  
    position: fixed;  
    background-color: #F8F8F8;  
    top: 0;  
    z-index: 999;  
}

给原生导航栏添加自定义按钮

注意:按钮的点击事件需要在页面监听onNavigationBarButtonTap事件

页面监听代码如下:

export default {  
    data() {  
        return {}  
    },  
    onNavigationBarButtonTap() {  
        console.log("点击了自定义按钮");  
    }  
}  

pages.json配置如下:

{  
    "path": "pages/log/log",  
    "style": {  
        "navigationBarTitleText": "hello",  
        "app-plus": {  
            "titleNView": {  
                "buttons": [{  
                    "text": "\ue534",  
                    "fontSrc": "/static/uni.ttf",  
                    "fontSize": "22px"  
                }]  
            }  
        }  
    }  
}

buttons的text推荐使用字体图标。
如果按钮使用的汉字或英文较长,推荐把字体改小一点,或者调节按钮宽度等值。
配置button的背景颜色为透明:background:'rgba(0,0,0,0)'

以上代码在hello uni-app的模板-顶部导航标题栏中有示例。

原生导航栏自定义按钮带红点和角标

{  
    "path" : "nav-dot/nav-dot",  
    "style" : {  
        "navigationBarTitleText" : "导航栏带红点和角标",  
        "app-plus" : {  
            "titleNView" : {  
                "buttons" : [  
                    {  
                        "text" : "消息",  
                        "fontSize" : "14",  
                        "redDot" : true  
                    },  
                    {  
                        "text" : "关注",  
                        "fontSize" : "14",  
                        "badgeText" : "12"  
                    }  
                ]  
            }  
        }  
    }  
}

以上代码在hello uni-app的模板-顶部导航标题栏中有示例。

原生导航栏自定义按钮带下拉选择(城市选择)

{  
    "path" : "nav-city-dropdown/nav-city-dropdown",  
    "style" : {  
        "navigationBarTitleText" : "导航栏带城市选择",  
        "app-plus" : {  
            "titleNView" : {  
                "buttons" : [  
                    {  
                        "text" : "北京市",  
                        "fontSize" : "14",  
                        "select" : true,  
                        "width" : "auto"  
                    }  
                ]  
            }  
        }  
    }  
}

以上代码在hello uni-app的模板-顶部导航标题栏中有示例。

导航栏上的原生搜索框

原生导航栏支持放置原生搜索框,可点击直接弹出软键盘,也可以点击后跳转到新页面搜索。
因代码较多,此处不列,请参考hello uni-app的模板-顶部导航标题栏示例。
如需动态修改searchInput,或者获取searchInput的placehold,参考uni-app动态修改App端导航栏

配置原生导航栏的透明渐变

原生导航栏还支持透明渐变效果,页面刚载入时没有导航标题,页面内容通顶到状态栏里,页面向下滚动后标题栏渐变出现。

{  
    "path": "pages/log/log",  
    "style": {  
        "navigationBarTitleText": "hello",  
        "app-plus": {  
            "titleNView": {  
                "type": "transparent"  
            }  
        }  
    }  
}

实际上可用的titleNView设置还有很多,详细的api见http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewTitleNViewStyles

透明渐变的导航栏的button图标有一个默认的灰色背景圈,防止背景图和按钮前景颜色相同导致按钮无法看清。如果要去掉这个灰色背景图,可以配置button的背景颜色为透明:background:'rgba(0,0,0,0)'

原生导航栏绘制图片

titleNView新版配置可以直接配图片,还支持Gif图。但这里提供一个黑科技写法,通过在titleNView里配置tags,可以实现导航栏绘制图片的效果:

{  
    "path" : "nav-image/nav-image",  
    "style" : {  
        "app-plus" : {  
            "titleNView" : {  
                "titleText" : "",  
                "tags" : [  
                    {  
                        "tag" : "img",  
                        "src" : "/static/nav.png",  
                        "position" : {  
                            "left" : "auto",  
                            "top" : "auto",  
                            "width" : "110px",  
                            "height" : "26px"  
                        }  
                    }  
                ]  
            }  
        }  
    }  
}

通过配置 tags 除了可以绘制图片,还可以绘制更多丰富的内容,如:richtext(富文本)、font(文本)、input(输入框)、rect(矩形区域)。详情参考:titleNViewtags

以上代码在hello uni-app的模板-顶部导航标题栏中有示例。

通过setStyle方式动态修改原生导航栏样式

如果需要js动态修改导航栏,uni有跨端的api可修改标题、背景色、前景色。这部分是app、小程序、h5都支持的,参考https://uniapp.dcloud.io/api/ui/navigationbar

对于app侧扩展的设置,比如自己添加的buttons,则需使用plus的js api来动态设置。在App端可以通过得到webview对象,通过setStyle方法重新设置,包括修改webview对象的titleNview属性,以达到修改标题栏按钮文字及样式的功能。
具体参考:https://ask.dcloud.net.cn/article/35374

App侧使用subnvue自行绘制原生导航

nvue其实是weex上补充了uni的api。
uni-app支持使用nvue页面,也就是weex原生引擎,绘制顶部的原生导航栏。
在hello uni-app的API-界面示例中,有subnvue示例,里面顶部导航栏是渐变色的,这就是subnvue的原生导航栏。

在pages.json的配置如下:

{  
    "path": "subnvue/subnvue",  
    "style": {  
        "app-plus": {  
            "titleNView": false,  
            "subNVues": [{  
                "id": "nav",  
                "path": "subnvue/subnvue/nav",  
                "type": "navigationBar"  
            }]  
        }  
    }  
}

更新:从HBuilderX2.6.3起,titleNView直接支持了背景图、渐变色,不再需要通过subnvue的方式了。而且性能比subnvue更好。

App侧使用plus.nativeObj.view自定义原生导航栏

注意:从HBuilderX 1.9.10起提供了subnvue,比使用plus.nativeObj.view自定义原生导航栏更加方便。详见上一节。

titleNView提供的配置,虽然比微信多不少,但有时仍然无法满足某些场景的需求,比如在titleNView中画一个选项卡。
此时有3种处理方式。1. 使用plus.nativeObj.view的api自定义titleNView。2. 页面采用nvue,即weex方式制作。3. 取消原生导航,使用view自行绘制(见上)。
本节先说方式1. 使用plus.nativeObj.view
plus.nativeObj是5+引擎提供的轻量原生渲染引擎,其中plus.nativeObj.view一个自定义性很强的对象,以下简称nview。
规范文档是:www.html5plus.org/doc/zh_cn/nativeobj.html#plus.nativeObj.View
nview是一个基于canvas理念的绘制引擎,在一块画布上自行绘制、覆盖、擦除。
nview可以画出任何界面、线条、矩形、文字、图片、包括原生的input输入框。
其实我们所看到的各种界面对象控件,在计算机底层都是绘图引擎基于draw字、draw图、draw线条来做的。
与weex相比,nview并不够强,nview没有dom概念,不支持内部滚动。
其实titleNView,包括原生tabbar、cover-view,他们的底层实现都是基于nview的。

获取当前页面的titleNView对象,参考http://ask.dcloud.net.cn/article/35036
同时上述参考文章中还有一个给titleNView的右上角画一个小红点的例子。

开发者制作的示例,如何给原生导航栏顶部画一个原生input:http://ask.dcloud.net.cn/article/35201

取消原生导航栏后,使用前端标签组件模拟绘制导航栏

不管是全局取消原生导航栏,还是在App下某个页面取消原生导航,如果还想自己绘制一些个性化的title,往往会使用view组件。
尤其是App的首页,顶部经常有各种特殊设置,此时需要自己使用前端技术来绘制导航。

导航栏应该是由状态栏和标题栏构成,状态栏的高度为 var(--status-bar-height) 此变量为uni-app框架提供仅在在css生效,标题栏的高度设为88px,整个状态栏的高度应为: calc(var(--status-bar-height) + 88px)
(upx主要针对宽度,高度无所谓还可以使用px)

.title-contents{  
    height: calc(var(--status-bar-height) + 88px);  
}  
.status{  
    height: var(--status-bar-height);  
}  
.titles{  
    height: 88px;  
}

状态栏和标题栏都应固定在页面顶部,需设置 position:fixed,标题栏的top应为状态栏的高度

.top-view{  
    width: 100%;  
    position: fixed;  
    top: 0;  
}  
.titles{  
    top: var(--status-bar-height);  
}

绘制的返回箭头需要绑定点击事件,返回上一个页面

<view class="titleLeftButton" @click="backButton"></view>  

methods:{  
    backButton(){  
        uni.navigateBack()  
    }  
}

以下为导航栏组件的部分代码

<template>  
    <view class="title-contents">  
        <view class="top-view status" :style="{background:statusColor}"></view>  
        <view class="_top titles" :style="{background:statusColor}">  
            <view class="titleLeftButton" @click="backButton" v-if="showLeftButton"></view>  
            <view class="titleText" :class="titleClass">{{titleText}}</view>  
            <view class="titleRightButton" @click="rightButton" v-if="showRightButton"></view>  
        </view>  
    </view>  
</template>  
<script>  
    export default {  
        props:{  
            titleText:{  
                type:String,  
                default:""  
            },  
            statusColor:{  
                type:String,  
                default:"#8F8F94"  
            },  
            showLeftButton:{  
                type:Boolean,  
                default:true  
            },  
            showRightButton:{  
                type:Boolean,  
                default:false  
            }  
        },  
        methods:{  
            backButton(){  
                uni.navigateBack()  
            },  
            ...  
        }  
    }  
</script>  
<style>  
    ...  
    .top-view{  
        width: 100%;  
        position: fixed;  
        top: 0;  
    }  
</style>  

Ps:若页面不需要标题栏,只需一个状态栏的view占位,那么只需在页面添加一个view即可不需要引入外部组件以免影响性能。

<view class="status-contents">  
    <view class="status top-view"></view>  
</view>
//css  
.status-contents{  
    height: var(--status-bar-height);  
}  
.top-view{  
    width: 100%;  
    position: fixed;  
    top: 0;  
}  
.status{  
    height:var(--status-bar-height);  
}

uni ui里有前端实现的自定义导航栏组件,推荐不要自己写,直接用写好的组件,https://ext.dcloud.net.cn/plugin?id=52,hello uni-app的uni ui中也有示例。

注意事项

取消原生导航栏后,自己使用HTML自定义组件模拟导航栏,会有很多性能体验问题:

  1. 加载不如原生导航快
  2. 下拉刷新无法从自定义的导航栏组件下面下拉。除非使用前端做下拉刷新,但性能不如自带的原生下拉刷新。
  3. 必须取消页面的bounce效果,否则滚动到顶时再拖屏幕,在iOS上发现title也被拖下来了。
  4. 滚动条会通顶
    所以除非不得以,不要取消原生导航栏。
    如必须使用,注意如下几点:
  5. 涉及到导航栏高度的css尽量放置在App.vue里面以提高渲染速度(css渲染顺序:先渲染App.vue里面的css,再渲染页面css)
  6. 如果是深色造成闪屏,需要在pages.json的titleNView下配置webview的背景色
  7. 状态栏颜色应设置默认颜色,若非必要,不建议修改其颜色
  8. 减少在组件中使用 :style="" 的使用以提高性能
  9. 下拉刷新使用circle方式,并设置offset,让下拉刷新的圈从指定位置开始下拉,具体见pages.json配置文档

有个高频场景是App“首页”的title自定义,如果实现的效果很个性化,那么使用plus.nativeObj.view的方案会过于复杂,由于首页并不存在新页面进入立即渲染的压力,所以App首页如果要大幅定制,推荐使用前端view绘制,而不是使用plus.nativeObj.view。

如果把自定义导航封装成组件,虽然多个页面引入方便,但性能下降,因为这种自定义组件的加载是晚于页面基本元素的,会导致新页面进入动画时无法渲染title。
所以导航条这种要求在动画期渲染的东西,尽量不要使用自定义组件方式。

在hello uni-app示例中有各种导航栏的源码。
在扩展ui中有前端自定义导航栏。
在模板中有各种原生的导航栏。
大多数情况复制这些代码就够了。

继续阅读 »

看示例,这里的功能比文档里写的多:https://ext.dcloud.net.cn/plugin?id=1765

本文虽长,但值得看完。可避免开发中的很多坑

uni-app 自带原生导航栏,在pages.json里配置。
原生导航的体验更好,渲染新页面时,原生导航栏的渲染无需等待新页面dom加载,可以在新页面进入动画开始时就渲染。

原生导航还可以避免滚动条通顶,并方便的控制原生下拉刷新。
通过pages.json的配置,可以简单的、跨端的、高性能的开发业务。

但原生导航栏的扩展能力有限的。尤其是微信下,没有提供太多导航栏的配置。
在App下,pages.json里每个页面的app-plus下可以设置titleNView等更多参数,可以得到比微信小程序更丰富的扩展性。
另外,开发者也可以在必要时取消原生导航栏,使用view自行绘制导航栏。

原生导航栏的通用配置

原生导航栏的配置,均在pages.json里,每个page下面的style配置中的navigationBar各个参数配置,即为通用配置,小程序、app、h5均生效。参考https://uniapp.dcloud.io/collocation/pages?id=style

全局取消原生导航栏

在pages.json的globalStyle里,有个navigationStyle设置,默认是default,即带有原生导航栏。
也可以设置为custom。
在设为custom后,所有页面都没有原生导航。
但在微信小程序里,右上角始终都有一个胶囊按钮。
很多微信小游戏界面上也没原生导航栏,但有胶囊按钮。
一般App里不会使用这个参数配置。建议个别页面单独设置不使用原生导航,具体见下。

单独去除原生导航栏

支持通过如下方法取消单独一个页面的原生导航栏。但小程序右上角胶囊按钮仍然去不掉。页面配置 navigationStyle 为 custom:

{  
    "path" : "pages/log/log",  
    "style" : {  
        "navigationStyle":"custom"  
    }  
}

原生导航栏在App侧的扩展

微信小程序的设计里,没有给原生导航提供太多自定义能力。在开发App时是不够用的。
pages.json里,每个page下面的style下面还有一个子扩展节点:app-plus。
这个节点定义了在5+App环境下,也即iOS、Android环境下,增强的配置。
其中有一个子节点titleNView,这个是5+规范里webview页面的原生导航窗体规范。
参考https://uniapp.dcloud.io/collocation/pages?id=app-plus

App去除导航栏后改变状态栏样式

App因为默认为沉浸式,去除导航栏后,页面顶部会直通到状态栏的区域,可能出现如下需求:

  • 改变状态栏文字颜色:设置该页面的 navigationBarTextStyle 属性,可取值为 black/white。如果想单独设置颜色,App端可使用plus.navigator.setStatusBarStyle设置。部分低端Android手机(4.4)自身不支持设置状态栏前景色。
  • 改变状态栏背景颜色:通过绘制一个占位的view固定放在状态栏位置,设置此view的背景颜色,即可达到想要的效果,uni-app提供了一个状态栏高度的css变量,具体参考:http://uniapp.dcloud.io/frame?id=css%E5%8F%98%E9%87%8F

以下为示例:

<!-- #ifdef APP-PLUS -->  
<view class="status_bar">  
    <view class="top_view"></view>  
</view>  
<!-- #endif -->
.status_bar {  
    height: var(--status-bar-height);  
    width: 100%;  
    background-color: #F8F8F8;  
}  
.top_view {  
    height: var(--status-bar-height);  
    width: 100%;  
    position: fixed;  
    background-color: #F8F8F8;  
    top: 0;  
    z-index: 999;  
}

给原生导航栏添加自定义按钮

注意:按钮的点击事件需要在页面监听onNavigationBarButtonTap事件

页面监听代码如下:

export default {  
    data() {  
        return {}  
    },  
    onNavigationBarButtonTap() {  
        console.log("点击了自定义按钮");  
    }  
}  

pages.json配置如下:

{  
    "path": "pages/log/log",  
    "style": {  
        "navigationBarTitleText": "hello",  
        "app-plus": {  
            "titleNView": {  
                "buttons": [{  
                    "text": "\ue534",  
                    "fontSrc": "/static/uni.ttf",  
                    "fontSize": "22px"  
                }]  
            }  
        }  
    }  
}

buttons的text推荐使用字体图标。
如果按钮使用的汉字或英文较长,推荐把字体改小一点,或者调节按钮宽度等值。
配置button的背景颜色为透明:background:'rgba(0,0,0,0)'

以上代码在hello uni-app的模板-顶部导航标题栏中有示例。

原生导航栏自定义按钮带红点和角标

{  
    "path" : "nav-dot/nav-dot",  
    "style" : {  
        "navigationBarTitleText" : "导航栏带红点和角标",  
        "app-plus" : {  
            "titleNView" : {  
                "buttons" : [  
                    {  
                        "text" : "消息",  
                        "fontSize" : "14",  
                        "redDot" : true  
                    },  
                    {  
                        "text" : "关注",  
                        "fontSize" : "14",  
                        "badgeText" : "12"  
                    }  
                ]  
            }  
        }  
    }  
}

以上代码在hello uni-app的模板-顶部导航标题栏中有示例。

原生导航栏自定义按钮带下拉选择(城市选择)

{  
    "path" : "nav-city-dropdown/nav-city-dropdown",  
    "style" : {  
        "navigationBarTitleText" : "导航栏带城市选择",  
        "app-plus" : {  
            "titleNView" : {  
                "buttons" : [  
                    {  
                        "text" : "北京市",  
                        "fontSize" : "14",  
                        "select" : true,  
                        "width" : "auto"  
                    }  
                ]  
            }  
        }  
    }  
}

以上代码在hello uni-app的模板-顶部导航标题栏中有示例。

导航栏上的原生搜索框

原生导航栏支持放置原生搜索框,可点击直接弹出软键盘,也可以点击后跳转到新页面搜索。
因代码较多,此处不列,请参考hello uni-app的模板-顶部导航标题栏示例。
如需动态修改searchInput,或者获取searchInput的placehold,参考uni-app动态修改App端导航栏

配置原生导航栏的透明渐变

原生导航栏还支持透明渐变效果,页面刚载入时没有导航标题,页面内容通顶到状态栏里,页面向下滚动后标题栏渐变出现。

{  
    "path": "pages/log/log",  
    "style": {  
        "navigationBarTitleText": "hello",  
        "app-plus": {  
            "titleNView": {  
                "type": "transparent"  
            }  
        }  
    }  
}

实际上可用的titleNView设置还有很多,详细的api见http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewTitleNViewStyles

透明渐变的导航栏的button图标有一个默认的灰色背景圈,防止背景图和按钮前景颜色相同导致按钮无法看清。如果要去掉这个灰色背景图,可以配置button的背景颜色为透明:background:'rgba(0,0,0,0)'

原生导航栏绘制图片

titleNView新版配置可以直接配图片,还支持Gif图。但这里提供一个黑科技写法,通过在titleNView里配置tags,可以实现导航栏绘制图片的效果:

{  
    "path" : "nav-image/nav-image",  
    "style" : {  
        "app-plus" : {  
            "titleNView" : {  
                "titleText" : "",  
                "tags" : [  
                    {  
                        "tag" : "img",  
                        "src" : "/static/nav.png",  
                        "position" : {  
                            "left" : "auto",  
                            "top" : "auto",  
                            "width" : "110px",  
                            "height" : "26px"  
                        }  
                    }  
                ]  
            }  
        }  
    }  
}

通过配置 tags 除了可以绘制图片,还可以绘制更多丰富的内容,如:richtext(富文本)、font(文本)、input(输入框)、rect(矩形区域)。详情参考:titleNViewtags

以上代码在hello uni-app的模板-顶部导航标题栏中有示例。

通过setStyle方式动态修改原生导航栏样式

如果需要js动态修改导航栏,uni有跨端的api可修改标题、背景色、前景色。这部分是app、小程序、h5都支持的,参考https://uniapp.dcloud.io/api/ui/navigationbar

对于app侧扩展的设置,比如自己添加的buttons,则需使用plus的js api来动态设置。在App端可以通过得到webview对象,通过setStyle方法重新设置,包括修改webview对象的titleNview属性,以达到修改标题栏按钮文字及样式的功能。
具体参考:https://ask.dcloud.net.cn/article/35374

App侧使用subnvue自行绘制原生导航

nvue其实是weex上补充了uni的api。
uni-app支持使用nvue页面,也就是weex原生引擎,绘制顶部的原生导航栏。
在hello uni-app的API-界面示例中,有subnvue示例,里面顶部导航栏是渐变色的,这就是subnvue的原生导航栏。

在pages.json的配置如下:

{  
    "path": "subnvue/subnvue",  
    "style": {  
        "app-plus": {  
            "titleNView": false,  
            "subNVues": [{  
                "id": "nav",  
                "path": "subnvue/subnvue/nav",  
                "type": "navigationBar"  
            }]  
        }  
    }  
}

更新:从HBuilderX2.6.3起,titleNView直接支持了背景图、渐变色,不再需要通过subnvue的方式了。而且性能比subnvue更好。

App侧使用plus.nativeObj.view自定义原生导航栏

注意:从HBuilderX 1.9.10起提供了subnvue,比使用plus.nativeObj.view自定义原生导航栏更加方便。详见上一节。

titleNView提供的配置,虽然比微信多不少,但有时仍然无法满足某些场景的需求,比如在titleNView中画一个选项卡。
此时有3种处理方式。1. 使用plus.nativeObj.view的api自定义titleNView。2. 页面采用nvue,即weex方式制作。3. 取消原生导航,使用view自行绘制(见上)。
本节先说方式1. 使用plus.nativeObj.view
plus.nativeObj是5+引擎提供的轻量原生渲染引擎,其中plus.nativeObj.view一个自定义性很强的对象,以下简称nview。
规范文档是:www.html5plus.org/doc/zh_cn/nativeobj.html#plus.nativeObj.View
nview是一个基于canvas理念的绘制引擎,在一块画布上自行绘制、覆盖、擦除。
nview可以画出任何界面、线条、矩形、文字、图片、包括原生的input输入框。
其实我们所看到的各种界面对象控件,在计算机底层都是绘图引擎基于draw字、draw图、draw线条来做的。
与weex相比,nview并不够强,nview没有dom概念,不支持内部滚动。
其实titleNView,包括原生tabbar、cover-view,他们的底层实现都是基于nview的。

获取当前页面的titleNView对象,参考http://ask.dcloud.net.cn/article/35036
同时上述参考文章中还有一个给titleNView的右上角画一个小红点的例子。

开发者制作的示例,如何给原生导航栏顶部画一个原生input:http://ask.dcloud.net.cn/article/35201

取消原生导航栏后,使用前端标签组件模拟绘制导航栏

不管是全局取消原生导航栏,还是在App下某个页面取消原生导航,如果还想自己绘制一些个性化的title,往往会使用view组件。
尤其是App的首页,顶部经常有各种特殊设置,此时需要自己使用前端技术来绘制导航。

导航栏应该是由状态栏和标题栏构成,状态栏的高度为 var(--status-bar-height) 此变量为uni-app框架提供仅在在css生效,标题栏的高度设为88px,整个状态栏的高度应为: calc(var(--status-bar-height) + 88px)
(upx主要针对宽度,高度无所谓还可以使用px)

.title-contents{  
    height: calc(var(--status-bar-height) + 88px);  
}  
.status{  
    height: var(--status-bar-height);  
}  
.titles{  
    height: 88px;  
}

状态栏和标题栏都应固定在页面顶部,需设置 position:fixed,标题栏的top应为状态栏的高度

.top-view{  
    width: 100%;  
    position: fixed;  
    top: 0;  
}  
.titles{  
    top: var(--status-bar-height);  
}

绘制的返回箭头需要绑定点击事件,返回上一个页面

<view class="titleLeftButton" @click="backButton"></view>  

methods:{  
    backButton(){  
        uni.navigateBack()  
    }  
}

以下为导航栏组件的部分代码

<template>  
    <view class="title-contents">  
        <view class="top-view status" :style="{background:statusColor}"></view>  
        <view class="_top titles" :style="{background:statusColor}">  
            <view class="titleLeftButton" @click="backButton" v-if="showLeftButton"></view>  
            <view class="titleText" :class="titleClass">{{titleText}}</view>  
            <view class="titleRightButton" @click="rightButton" v-if="showRightButton"></view>  
        </view>  
    </view>  
</template>  
<script>  
    export default {  
        props:{  
            titleText:{  
                type:String,  
                default:""  
            },  
            statusColor:{  
                type:String,  
                default:"#8F8F94"  
            },  
            showLeftButton:{  
                type:Boolean,  
                default:true  
            },  
            showRightButton:{  
                type:Boolean,  
                default:false  
            }  
        },  
        methods:{  
            backButton(){  
                uni.navigateBack()  
            },  
            ...  
        }  
    }  
</script>  
<style>  
    ...  
    .top-view{  
        width: 100%;  
        position: fixed;  
        top: 0;  
    }  
</style>  

Ps:若页面不需要标题栏,只需一个状态栏的view占位,那么只需在页面添加一个view即可不需要引入外部组件以免影响性能。

<view class="status-contents">  
    <view class="status top-view"></view>  
</view>
//css  
.status-contents{  
    height: var(--status-bar-height);  
}  
.top-view{  
    width: 100%;  
    position: fixed;  
    top: 0;  
}  
.status{  
    height:var(--status-bar-height);  
}

uni ui里有前端实现的自定义导航栏组件,推荐不要自己写,直接用写好的组件,https://ext.dcloud.net.cn/plugin?id=52,hello uni-app的uni ui中也有示例。

注意事项

取消原生导航栏后,自己使用HTML自定义组件模拟导航栏,会有很多性能体验问题:

  1. 加载不如原生导航快
  2. 下拉刷新无法从自定义的导航栏组件下面下拉。除非使用前端做下拉刷新,但性能不如自带的原生下拉刷新。
  3. 必须取消页面的bounce效果,否则滚动到顶时再拖屏幕,在iOS上发现title也被拖下来了。
  4. 滚动条会通顶
    所以除非不得以,不要取消原生导航栏。
    如必须使用,注意如下几点:
  5. 涉及到导航栏高度的css尽量放置在App.vue里面以提高渲染速度(css渲染顺序:先渲染App.vue里面的css,再渲染页面css)
  6. 如果是深色造成闪屏,需要在pages.json的titleNView下配置webview的背景色
  7. 状态栏颜色应设置默认颜色,若非必要,不建议修改其颜色
  8. 减少在组件中使用 :style="" 的使用以提高性能
  9. 下拉刷新使用circle方式,并设置offset,让下拉刷新的圈从指定位置开始下拉,具体见pages.json配置文档

有个高频场景是App“首页”的title自定义,如果实现的效果很个性化,那么使用plus.nativeObj.view的方案会过于复杂,由于首页并不存在新页面进入立即渲染的压力,所以App首页如果要大幅定制,推荐使用前端view绘制,而不是使用plus.nativeObj.view。

如果把自定义导航封装成组件,虽然多个页面引入方便,但性能下降,因为这种自定义组件的加载是晚于页面基本元素的,会导致新页面进入动画时无法渲染title。
所以导航条这种要求在动画期渲染的东西,尽量不要使用自定义组件方式。

在hello uni-app示例中有各种导航栏的源码。
在扩展ui中有前端自定义导航栏。
在模板中有各种原生的导航栏。
大多数情况复制这些代码就够了。

收起阅读 »