架构分析
技术栈架构图:
项目架构分为三个部分:
1)客户端:H5/IOS/Android/小程序
2)服务端:JAVA数据交互层
具体分析:
H5的技术栈有好几种,这里个人推荐使用VUE,因为后面的更新迭代,我们可能会使用MUI最新的一套uni-app,它是基于Vue的,为了之后修改少部分的代码就可以更新迭代。
之所以现在还不使用这套uni-app,因为它目前发布了小程序丶APP,还没有发布H5版本的,后面会发布的。
(By the way 11月14日-16日于多伦多小右发表了名为 “ Vue 3.0 Updates ” 的主题演讲,概括起来就是more faster more easier)
Vue3.0特点:
1、更快
Virtual DOM 完全重写,mounting & patching 提速 100% ;
更多编译时(compile-time)提醒以减少 runtime 开销;
基于 Proxy 观察者机制以满足全语言覆盖及更好的性能;
放弃 Object.defineProperty ,使用更快的原生 Proxy ;
组件实例初始化速度提高 100% ;
提速一倍/内存使用降低一半。
2、更小
3、更易维护
4、更易于原生
5、让开发者更轻松
二丶使用MUI发布APP
我们使用H5+APP这套来开发,然后我们可以发布Android丶IOS的APP应用。
(MUI后面我们会讲很详细的)
三丶服务端
服务端我们使用JAVA,这里需要注意一点,后端开发人员要处理允许跨域调用,而且要允许option的访问,对option进行过滤。
MUI简介
Mui追求性能体验,它是最接近原生APP体验的高性能前端框架。
MUI的特点是:轻量、原生UI、流畅体验。
体验
从上面的架构分析,我们可以很清晰的看到,我们是使用H5来开发的。
MUI UI 控件:
UI 列表:
体验版:
可以体验我写出来的Demo,里面有一个调用生产的demo,调用用户登录查询接口。
后端开发人员需要注意一点:允许跨域调用,而且要允许option的访问,对option进行过滤。
注意事项
在讲解代码之前,我们要注意几个点:
1丶固定栏靠前
固定栏,就是带有.mui-bar属性的节点,都是基于fixed定位的元素;
常见组件包括:
顶部导航栏(.mui-bar-nav)、底部工具条(.mui-bar-footer)、底部选项卡(.mui-bar-tab);
这些元素使用时需遵循一个规则:
放在.mui-content元素之前,即使是底部工具条和底部选项卡,也要放在.mui-content之前,否则固定栏会遮住部分主内容;
2丶一切内容都要包裹在mui-content中
除了固定栏之外,其它内容都要包裹在.mui-content中,否则就有可能被固定栏遮罩。
原因:固定栏基于Fixed定位,不受流式布局限制,普通内容依然会从top:0的位置开始布局,这样就会被固定栏遮罩。
mui为了解决这个问题,定义了如下css代码:
.mui-bar-nav ~ .mui-content {
padding-top: 44px;
}
.mui-bar-footer ~ .mui-content {
padding-bottom: 44px;
}
.mui-bar-tab ~ .mui-content {
padding-bottom: 50px;
}
当然拉,这个是H5开发,所以也可以自定义样式。everything is ok。
3丶始终为button按钮添加type属性
如果button按钮没有type属性,浏览器默认按照type=submit逻辑处理,这样若将没有type的button放在form表单中,点击按钮就会执行form表单提交,页面就会刷新,用户体验极差。
4丶页面初始化:必须执行mui.init方法
mui在页面初始化时,初始化了很多参数配置,比如:按键监听、手势监听等,因此mui页面都必须调用一次mui.init()方法;
5丶页面跳转:抛弃href跳转
建议使用mui.openWindow方法打开一个新的webview,mui会自动监听新页面的loaded事件,若加载完毕,再自动显示新页面;
有兴趣深入了解,拓展链接:
hello mui中的无等待窗体切换是如何实现的
提示HTML5的性能体验系列之一 避免切页白屏
6丶点击:忘记click
手机浏览器的click点击存在300毫秒延迟,mui为了解决这个问题,封装了tap事件,因此在任何点击的时候,请忘记click及onclick操作,统统使用如下代码:
element.addEventListener('tap',function(){
//点击响应逻辑
});
这里讲解下,为什么click会有300ms:
双击缩放(double tap to zoom)
当用户一次点击屏幕之后,浏览器并不能立刻判断用户是要进行双击缩放,还是想要进行单击操作。因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕。
于是,300 毫秒延迟就这么诞生了。
最后有个点需要注意的:
mui为简化开发,将plusReady事件封装成了mui.plusReady()方法,凡涉及到HTML5+的api,建议都写在mui.plusReady方法中;
否则可能会报“plus is not defined”的错误;
安装开发工具
我发在群里的包就可以直接使用了,它运行时的占用内存比普元那套少了将近5倍。
正文
上面讲解了技术框架丶注意事项。下面我们开始进行详细的讲解。
使用webview
在邮我行发布项目,我们要基于H5来开发,所以使用webview。
Demo:
<div id="container" width="100%" height="100%" layout="VBox" hAlign="center" vAlign="middle" >
<webview id="webview" width="100%" height="100%" />
</div>
$M.page.addEvent('onLoad', function(params){
// 设置网络URL
webview.setUrl("your url");
});
// 设置状态栏颜色
Utils.setStatusBarStyle('default');
代码分析:
我们使用了webview组件,通过设置url,就可以访问我们的应用。
可以自行通过setStatusBarStyle设置状态栏的颜色,有两种模式default/light
答疑
看到上面的代码,可能有的同事可以会问,那在邮我行发布,我们使用H5开发,怎么调用手机里面的Api呢。下面举个例子:
html:
<div class="mui-page-content">
<p id="scaleText">扫一扫后结果内容显示</p>
<button id="onScale" onclick="getScaleData()" type="button" class="mui-btn mui-btn-green">扫一扫</button>
</div>
js:
function getScaleData () {
// 调用邮我行的提供的API扫一扫
Emp.execute("Utils.startBarCodeScanner(function(val){webview.execute('setPhTML(\"'+val+'\")')})");
}
function setPhTML (val) {
scaleText.innerHTML = val;
}
代码分析:
在页面写了个按钮和一个显示扫一扫后的结果显示文本。
通过按钮调用邮我行提供的扫一扫API,然后在扫完后调用H5页面的方法,把值设置到H5页面用来显示文本的地方就可以了。
温馨提示:
上面的例子,我使用了onclick方法,调用事件,这里是给个反面的例子,尽量不要使用click,上面的注意事项也已经讲了。
所以我们的代码要这样写:
document.getElementById('onScale').addEventListener('tap', function() {
Emp.execute("Utils.startBarCodeScanner(function(val){webview.execute('setPhTML(\"'+val+'\")')})");
})
通过这种方式,如果在邮我行上发布的项目,要调用手机的API,我们就需要使用这种方式来实现。
如果是通过mui打包发行的我们直接使用mui提供的API就可以了,不需要调用邮我行的API。
Mui API Reference
通过扫描上面的UI二维码,我们可以看到MUI的UI控件是很齐全的,基本市面上有的,它基本都有。
UI控件的使用,这里就不额外讲解了,把文档的Demo拉下来就能看到效果了。
M ui提供了以下调用手机API的接口,看图:
上面的接口参考,我们可以把例子拉下来就可以运行的拉,但是记得一点,这些接口要使用mui打包才能使用。
如果是在邮我行上发布的,我们还是得使用上面调用邮我行的例子。
Mui 窗口管理
Mui 窗口管理包括5个部分,分别是:
1.页面初始化
2.创建子页面
3.打开新页面
4.关闭页面
5.预加载
从一个页面点击链接跳转到另一个页面,这是我们会经常使用到的。
mui的思路是:单webview只承载单个页面的dom,减少dom层级及页面大小;
页面切换使用原生动画,将最耗性能的部分交给原生实现.
这里我们讲一个例子,加深大家的理解:
html:
<li class="mui-table-view-cell" id="muiLocationDom">
<a id="location" class="mui-navigate-right">页面跳转</a>
</li>
js:
document.getElementById('location').addEventListener('tap', function() {
mui.openWindow({
url: 'mapLocation.html',
id: 'mapLocation.html',
extras:{
name:'mui' // 自定义扩展参数,可以用来处理页面间传值
},
show: {
aniShow: 'pop-in'
},
waiting: {
autoShow: false
}
});
})
Mui 事件管理
事件管理有以下事件:
1.单击屏幕tap
2.双击屏幕doubletap
3.长按屏幕longtap
4.按住屏幕hold
5.离开屏幕release
6.向左滑动swipeleft
7.向右滑动swiperight
8.向上滑动swipeup
9.向下滑动swipedown
10.开始拖动dragstart
11.拖动中drag
12.拖动结束dragend
为了开发出更高性能的moble App,mui支持用户根据实际业务需求,通过mui.init方法中的gestureConfig参数,配置具体需要监听的手势事件。
mui.init({
gestureConfig:{
tap: true, //默认为true
doubletap: true, //默认为false
longtap: true, //默认为false
swipe: true, //默认为true
drag: true, //默认为true
hold:false,//默认为false,不监听
release:false//默认为false,不监听
}
});
自定义事件
添加自定义事件监听操作和标准js事件监听类似,可直接通过window对象添加,代码如下:
window.addEventListener('customEvent',function(event){
//通过event.detail可获得传递过来的参数内容
....
});
通过mui.fire()方法可触发目标窗口的自定义事件。
.fire( target , event , data )
参数说明:
1)target
Type: WebviewObject (需传值的目标webview)
2)event
Type: String 自定义事件名称
3)data
Type: JSON json格式的数据
具体例子
列表页面逻辑:
//初始化预加载详情页面
mui.init({
preloadPages:[{
id:'detail.html',
url:'detail.html'
}
]
});
var detailPage = null;
//添加列表项的点击事件
mui('.mui-content').on('tap', 'a', function(e) {
var id = this.getAttribute('id');
//获得详情页面
if(!detailPage){
detailPage = plus.webview.getWebviewById('detail.html');
}
//触发详情页面的newsId事件
mui.fire(detailPage,'newsId',{
id:id
});
//打开详情页面
mui.openWindow({
id:'detail.html'
});
});
详情页面逻辑:
//添加newId自定义事件监听
window.addEventListener('newsId',function(event){
//获得事件参数
var id = event.detail.id;
//根据id向服务器请求新闻详情
.....
});
Mui Ajax
mui框架基于htm5plus的XMLHttpRequest,封装了常用的Ajax函数,支持GET、POST请求方式,支持返回json、xml、html、text、script数据类型; 本着极简的设计原则,mui提供了mui.ajax方法,并在mui.ajax方法基础上,进一步简化出最常用的mui.get()、mui.getJSON()、mui.post()三个方法。
我们以mui.ajax,讲解一个例子。
html:
<button type="button" class="mui-btn mui-btn-blue" id="getRole">调用接口按钮</button>
js:
document.getElementById('getRole').addEventListener('tap', function() {
mui.ajax('your url',{
data: {
username:"username",
sercet:"222",
},
dataType:'json',//服务器返回json格式数据
type:'get',//HTTP请求类型
headers:{'Content-Type':'application/jsonapplication/json;charset=UTF-8'},
timeout:10000,//超时时间设置为10秒;
success:function(data){
//服务器返回响应,根据响应结果,分析是否登录成功;
alert(data)
},
error:function(xhr,type,errorThrown){
//异常处理;
alert(JSON.stringify(type))
}
});
})
温馨提示:后端开发人员要处理允许跨域调用,而且要允许option的访问,对option进行过滤。
代码块–快捷开发
&nbs; mui为开发者提供了常用的代码块,我们只需要敲几个字母,就可以生成对应的代码块。
代码块链接
结语
文末,个人建议:减少css二次渲染,就是少用复杂的选择器,少用padding、margin这些会二次修正页面的css。 如果追求极致的话,那jquery、zepto这些框架也不要使用,手机上都是webkit引擎,直接写document的api操作dom即没有兼容问题又没有效率问题。
常用文档地址汇总
MUI是开源,它的社区是很活跃的,有问必答。我把常用的文档地址收集在这里,方便大家查找。
原生UI http://dev.dcloud.net.cn/mui/ui/
窗口管理 http://dev.dcloud.net.cn/mui/window/
事件管理 http://dev.dcloud.net.cn/mui/event/
util http://dev.dcloud.net.cn/mui/util/
util说明:
mui框架将很多功能配置都集中在mui.init方法中,要使用某项功能,只需要在mui.init方法中完成对应参数配置即可,
目前支持在mui.init方法中配置的功能包括:
&nbs; 创建子页面、关闭页面、手势事件配置、预加载、下拉刷新、上拉加载、设置系统状态栏背景颜色。
ajax http://dev.dcloud.net.cn/mui/ajax/
下拉刷新 dev.dcloud.net.cn/mui/pulldown/
上拉加载 http://dev.dcloud.net.cn/mui/pullup/
快捷代码块 http://dev.dcloud.net.cn/mui/snippet/
修改mui默认的图标 http://ask.dcloud.net.cn/article/128
自定义mui控件样式
样式代码覆盖,覆盖mui默认的。
需要注意一点:
sass文件开源,自己修改sass并编译也可以;但是如果mui升级了,需要自己手动升级 (一般不建议改这里)。
页面间传值 http://ask.dcloud.net.cn/article/63
自定义事件 http://dev.dcloud.net.cn/mui/event/#customevent
5 + APP API Reference http://www.html5plus.org/doc/h5p.html