Hello MUI发布列表到详情最佳实践

Hello MUI在“模板”分类中增加了“列表到详情最佳实践”,先看效果:

列表到详情最佳实践

从如上gif图中,可看出本示例的主要特点:点击列表瞬间打开详情页,并且详情页已渲染完毕,效果堪比原生App!

本模板设计目标:演示在窗口动画期间完成页面渲染

下面简单介绍一下实现思路,开发者可以套用这个模板,修改服务端地址及对应业务参数,即可实现同样流畅平滑的窗口切换效果。

实现思路:

\n

预加载详情页

\n

在列表页中预加载详情页,列表页中点击某新闻时,通过自定义事件通知详情页加载对应新闻详情,这样可以避免每次打开新闻详情时重新创建webview的资源消耗。

mui.plusReady(function() {
//预加载详情页
webview_detail = mui.preload({
url: 'detail.html',
id: 'vue_demo_detail',
styles: {
"render": "always",//一直渲染
"popGesture": "hide",
"titleNView": titleNView//使用原生渐变导航
}
});
});
\n

复用前页数据

\n

详情页的内容需要通过ajax从服务端动态获取,获取之后再渲染,这里需要耗费一定的时间;如果网络不好,用户就会看到白屏或空页面,体验不好;
实际上,详情页部分内容在列表页已经加载过,可以直接从列表页传递过来(自定义事件耗时<10毫秒),而无需等待网络响应(ajax耗时 > 50毫秒)。因此,在列表页点击事件中,将列表页已加载的、详情页也需要的信息通过自定义事件传递给详情页,详情页将这些数据立即渲染,然后再通过ajax动态获取其余部分的数据。

1、列表页点击事件中传递已加载数据

//触发子窗口变更新闻详情
mui.fire(webview_detail, 'get_detail', {
guid: guid,
title:title,
author:author,
time:time,
cover:cover
});
\n

2、详情页获取前页数据后,立即渲染,再通过ajx请求其余数据

//监听自定义事件,获取新闻详情
document.addEventListener('get_detail', function(event) {
var guid = event.detail.guid;
if(!guid) {
return;
}
//前页传入的数据,直接渲染,无需等待ajax请求详情后
vm.cover = event.detail.cover;
vm.title = event.detail.title;
vm.author = event.detail.author;
vm.time = event.detail.time;
//向服务端请求文章详情内容
mui.ajax('your-server-url' + guid, {
type:'GET',
dataType: 'json', //服务器返回json格式数据
timeout: 15000, //15秒超时
success: function(rsp) {
vm.content = rsp.content;
},
error: function(xhr, type, errorThrown) {
mui.toast('获取文章内容失败');
//TODO 此处可以向服务端告警
}
});
});
\n

详情页返回时重置页面数据

\n

为了避免打开下一个新闻详情时,闪一下上一个新闻详情,模板在详情页返回时,会清空详情页数据;因为本模板使用了vue框架,实际上执行的就是重置vue数据。

实现较为简单,重写mui.back,代码示例如下:

//重写返回逻辑,返回时隐藏详情页webview
mui.back = function() {
plus.webview.currentWebview().hide("auto", 300);
}
//窗口隐藏时,重置页面数据
mui.plusReady(function () {
var self = plus.webview.currentWebview();
self.addEventListener("hide",function (e) {
window.scrollTo(0, 0);//重置滚动条位置
vm.resetData();//重置页面数据
},false);
})
\n

其中,vm.resetData()为清空vue数据的方法。

致谢,感谢 @redonion42@163.com 建议,通过hide事件同时处理back按键、侧滑返回的重置需求。

提高网络响应

\n

核心实现就如上两点,开发者按照这种模板就可以做出同样流畅的App。如果发现响应缓慢,注意检查两点:

  • 减少网络传输量,让服务端仅返回前端需要的字段
  • 利用缓存等技术优化服务端响应,保证ajax请求可以在100毫秒之内获得响应
\n

关联功能点

\n

按照如上思路实现的“列表到详情最佳实践”,还牵扯到一些关联知识点:

1、集成vue
本示例的列表页、详情页均使用了vue框架实现数据绑定,涉及到vue的列表渲染、数据重置知识点,内容较为简单,源码完全开源,本文不再详述。

2、下拉刷新
列表页集成了单webview下拉刷新,性能更好,代码示例如下:

//mui初始化,配置下拉刷新
mui.init({
pullRefresh: {
container: '#list',
down: {
style: 'circle',
offset: '0px',
auto: true,//自动触发下拉刷新
callback: function() {
//TODO 下拉刷新回调
}
}
}
});
\n

3、透明渐变导航
详情页使用了原生版本的透明渐变导航,参考教程

在点击不同新闻详情页时,需要改变原生导航条上的标题内容,通过重新设置webview的style属性即可,示例如下:

    //更改详情页原生导航条信息
titleNView.titleText = title;
webview_detail.setStyle({
"titleNView": titleNView
});
\n

Hello MUI中体验

\n

最新版的Hello MUI已集成了"列表到详情最佳实践",在即将发版的HBuilder 8.8.0 版本中即可体验,体验路径:Hello MUI首页--> 列表到详情最佳实践


17 分享
lhyh without_bug DCloud_客服_Trust 汪汪的一群羊 yungehaha mackes 13653439593@163.com 826198755@qq.com 18715019130@163.com 屋顶上的野蛮人 杰哥seo zyh@ulimei.com 2523732076@qq.com 919007628@qq.com fsjungle@qq.com atongmu 辉辉
带头大兵

带头大兵

为什么没有上拉加载?
0 赞 2 天前
atongmu

atongmu

mark
0 赞 2017-10-19 13:30
DCloud_MUI_CHB

DCloud_MUI_CHB 回复 footerhy@163.com

HBuilder中新建Hello MUI工程,有完整源码,这里只是代码示例片段
0 赞 2017-09-27 21:54
footerhy@163.com

footerhy@163.com

vm是哪里的变量
0 赞 2017-09-27 21:07
qq421065846

qq421065846

从七月中旬开始做混合app,到8月中下旬app上线。已经完成了一个简单的app并且在腾讯和苹果appstore上线了,这期间遇到过无数的坑,主要是熟悉和使用mui框架,h5+,以及调用原生api等,入坑已深,现在正准备开发一款旅游类的混合app,原型图已经出。现在准备开工了。同时,希望有一起做混合app的,有兴趣加qq群654230427一起讨论交流学习,爬坑,共同进步。
1 赞 2017-09-11 22:26
409346029@qq.com

409346029@qq.com 回复 DCloud_MUI_CHB

你好请问如果想查看此demo示例,是要在Hbuilder8.8.0 里 文件 => 新建 => 移动App =>Hello H5+,然后打包成原生APP吗?
0 赞 2017-09-04 15:45
DCloud_MUI_CHB

DCloud_MUI_CHB 回复 409346029@qq.com

列表到详情最佳实践,是在App环境下运行的,因为涉及预加载、多webview通讯等,不适合浏览器环境下运行。
0 赞 2017-09-01 16:54
409346029@qq.com

409346029@qq.com

这个项目我怎么无法预览?用浏览器会报错.我下载了Hbuilder 8.8.0 新建Hello Mui 模板 index=>列表到详情页最佳实践 直接报错误?
1.Cannot read property 'addEventListener' of undefined
1.Cannot read property 'offsetWidth' of undefined
0 赞 2017-09-01 14:58
DCloud_MUI_CHB

DCloud_MUI_CHB 回复 头上有灰机

1、index可以和首页4个选项卡复用,也就是启动时5个webview可以变4个
2、只有重要页面、用户希望尽快看到内容的业务需要预加载,无需预加载每一个页面
0 赞 2017-08-29 18:47
头上有灰机

头上有灰机

按这个方法实现了预加载, 挺好的, 尤其是返回时要重置数据这点细节很棒. 第一次使用预加载, 有个疑问, 预加载页面一般多少个以内比较合适?

我现在APP首页,进来就有4个选项卡,加上底部菜单,加上index,就相当于APP一打开,就有一个webview,再加5个子webview,,然后首页的列表有文章、活动、投票,还有文章分类,如果全部采用预加载,就又多了4个,,这样会不会有性能问题?第一次接触这种app开发
0 赞 2017-08-29 15:42
dwchyz

dwchyz

dcloud一直在叫板原生!有什么好叫板的?我想说的是,做好现有的,规划未来的!webapp是永远都无法超载原生的!这是天生的!
0 赞 2017-08-26 01:44
919007628@qq.com

919007628@qq.com

实例看见了,确实体验很好,赞!
0 赞 2017-08-21 14:50
GodBless

GodBless 回复 taoliujun

一个直接操作dom,一个是帮你操作dom,性能能有都多大的区别。。。
0 赞 2017-08-08 09:47
qq421065846

qq421065846

从七月中旬开始做混合app,到现在半个月过去了,一个简单的app已见雏形,期间也遇到过无数的坑,主要是熟悉和使用mui框架,h5+,以及调用原生api等,入坑已深,欢迎有兴趣加qq421065846一起讨论交流学习,爬坑。
0 赞 2017-08-01 15:20
豌豆射手孟德尔

豌豆射手孟德尔 回复 taoliujun

好的,谢谢
0 赞 2017-07-28 06:55
taoliujun

taoliujun 回复 豌豆射手孟德尔

影响性能的是大量的dom操作、复杂的选择器、频繁的js动画。所以说jq会降低性能。
vue是做数据绑定用的,性能影响微乎其微
0 赞 2017-07-27 19:28
豌豆射手孟德尔

豌豆射手孟德尔 回复 taoliujun

官方说用jq框架会降低app性能,vue不会降低性能吗?
0 赞 2017-07-27 19:20
taoliujun

taoliujun 回复 豌豆射手孟德尔

vue不是必须的,你可以通过原生js方法来重写dom里的内容,比如标题、作者,文章内容。
2 赞 2017-07-27 16:08
豌豆射手孟德尔

豌豆射手孟德尔 回复 DCloud_MUI_CHB

这个还需要懂vue框架吗?
0 赞 2017-07-26 19:01
122687220@qq.com

122687220@qq.com

我想请问一下,照这种写法,如何在详情页拿到详情页中的原生导航栏对象(titleNView)?
0 赞 2017-07-12 00:00
GodBless

GodBless

安卓5.0手机,这里 Object.assign(this.$data, getDefaultData()); 报错。。
0 赞 2017-07-11 17:07
GodBless

GodBless 回复 southgate@qq.com

然而里面的下拉刷新也是个假的代码。。
0 赞 2017-07-11 14:03
GodBless

GodBless

详情页返回到列表页时,有明显闪动....
0 赞 2017-07-11 11:04
妙妙

妙妙

今天试了一下这个新功能,我用了tab的webview模式,第一个页面就是这个列表页,发现使用chrome调试工具真机调试时,只看到加载了main页的js和html,没有看到列表页的js和html,无法调试
0 赞 2017-07-03 20:56
southgate@qq.com

southgate@qq.com 回复 DCloud_MUI_CHB

这是个很不错的样板例子呢,最好同时能加上up事件的例子
0 赞 2017-06-29 04:34
DCloud_MUI_CHB

DCloud_MUI_CHB 回复 southgate@qq.com

这里代码确实不够严谨,不过此处情况一般不会发生(除非页面加载后,人手在50毫秒之内点击),最新示例已删除这块代码。
0 赞 2017-06-28 22:43
southgate@qq.com

southgate@qq.com

listview.html 的open_detail有点问题吧
//若详情页尚未预加载完成,则延时等待再执行
if(!webview_detail) {
setTimeout(function() {
open_detail(guid);
}, 100);
}
判断后应该加上retun,像这样
if(!webview_detail) {
setTimeout(function() {
open_detail(guid);
}, 100);
return;
}
1 赞 2017-06-28 22:37
DCloud_MUI_CHB

DCloud_MUI_CHB 回复 770343868@qq.com

这个最佳实践只能在5+ App和流应用中使用,H5网页不行
0 赞 2017-06-21 19:40
770343868@qq.com

770343868@qq.com

只能在app里用吗?H5网页端不能用是吗?
0 赞 2017-06-21 16:50
Viccy

Viccy

厉害了
0 赞 2017-06-16 17:23
redonion42@163.com

redonion42@163.com 回复 DCloud_MUI_CHB

不好意思,我没说清楚,我的意思是说back和popGesture这两个事件,可否封装一个方法同时监听这两个事件
0 赞 2017-06-16 11:52
DCloud_MUI_CHB

DCloud_MUI_CHB 回复 redonion42@163.com

hide是隐藏webview,popGesture有可能是隐藏,也有可能是关闭,看业务需求
0 赞 2017-06-16 11:34
近水楼台

近水楼台

mark
0 赞 2017-06-16 11:30
redonion42@163.com

redonion42@163.com 回复 DCloud_MUI_CHB

有没有考虑将两个事件合在一起呢,毕竟都是返回的操作
0 赞 2017-06-16 11:29
DCloud_MUI_CHB

DCloud_MUI_CHB 回复 redonion42@163.com

github上最新代码昨天已更新,增加了popGesture事件回调,侧滑结束后重置页面数据;不过,hide事件确实更好一点,可以同时处理back按键和侧滑返回
0 赞 2017-06-16 10:59
redonion42@163.com

redonion42@163.com

往上滚动一段距离然后侧滑返回,下一次进入详情页的时候还是处于之前滑动的位置,mui.back只重写点击击返回按钮的事件,对侧滑返回不起作用,最好在当前webView隐藏的时候处理重置页面数据。 plus.webview.currentWebview().addEventListener("hide",function(){
window.scrollTo(0, 0);
vm.resetData();
});
1 赞 2017-06-16 10:24
屋顶上的野蛮人

屋顶上的野蛮人

Dcloud真给力!
0 赞 2017-06-15 16:10
18715019130@163.com

18715019130@163.com

为啥我们公司开发APP不使用这个呢 不开森
0 赞 2017-06-14 13:41
yungehaha

yungehaha

貌似很厉害
0 赞 2017-06-14 10:06

要回复文章请先登录注册