uni-app Hello MUI发布列表到详情最佳实践
uni-app Hello MUI发布列表到详情最佳实践
Hello MUI在“模板”分类中增加了“列表到详情最佳实践”,先看效果:
从如上gif图中,可看出本示例的主要特点:点击列表瞬间打开详情页,并且详情页已渲染完毕,效果堪比原生App!
本模板设计目标:演示在窗口动画期间完成页面渲染
下面简单介绍一下实现思路,开发者可以套用这个模板,修改服务端地址及对应业务参数,即可实现同样流畅平滑的窗口切换效果。
实现思路:
预加载详情页
在列表页中预加载详情页,列表页中点击某新闻时,通过自定义事件通知详情页加载对应新闻详情,这样可以避免每次打开新闻详情时重新创建webview的资源消耗。
mui.plusReady(function() {
//预加载详情页
webview_detail = mui.preload({
url: 'detail.html',
id: 'vue_demo_detail',
styles: {
"render": "always",//一直渲染
"popGesture": "hide",
"titleNView": titleNView//使用原生渐变导航
}
});
});
复用前页数据
详情页的内容需要通过ajax从服务端动态获取,获取之后再渲染,这里需要耗费一定的时间;如果网络不好,用户就会看到白屏或空页面,体验不好; 实际上,详情页部分内容在列表页已经加载过,可以直接从列表页传递过来(自定义事件耗时<10毫秒),而无需等待网络响应(ajax耗时 > 50毫秒)。因此,在列表页点击事件中,将列表页已加载的、详情页也需要的信息通过自定义事件传递给详情页,详情页将这些数据立即渲染,然后再通过ajax动态获取其余部分的数据。
1、列表页点击事件中传递已加载数据
//触发子窗口变更新闻详情
mui.fire(webview_detail, 'get_detail', {
guid: guid,
title:title,
author:author,
time:time,
cover:cover
});
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 此处可以向服务端告警
}
});
});
详情页返回时重置页面数据
为了避免打开下一个新闻详情时,闪一下上一个新闻详情,模板在详情页返回时,会清空详情页数据;因为本模板使用了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);
})
其中,vm.resetData()为清空vue数据的方法。
提高网络响应
核心实现就如上两点,开发者按照这种模板就可以做出同样流畅的App。如果发现响应缓慢,注意检查两点:
- 减少网络传输量,让服务端仅返回前端需要的字段
- 利用缓存等技术优化服务端响应,保证ajax请求可以在100毫秒之内获得响应
关联功能点:
1、集成vue
本示例的列表页、详情页均使用了vue框架实现数据绑定,涉及到vue的列表渲染、数据重置知识点,内容较为简单,源码完全开源,本文不再详述。
2、下拉刷新、上拉加载
列表页集成了下拉刷新、上拉加载,代码示例如下:
mui.init({
pullRefresh: {
container: '#list',
down: {
style: 'circle',
offset: '0px',
auto: true,
callback: pulldownRefresh
},
up: {
contentrefresh: '正在加载...',
callback: pullupRefresh
}
}
});
相关教程参考:
3、透明渐变导航
详情页使用了原生版本的透明渐变导航,参考教程
在点击不同新闻详情页时,需要改变原生导航条上的标题内容,通过重新设置webview的style属性即可,示例如下:
//更改详情页原生导航条信息
titleNView.titleText = title;
webview_detail.setStyle({
"titleNView": titleNView
});
Hello MUI中体验
最新版的Hello MUI已集成了"列表到详情最佳实践",在HBuilder 8.8.0+ 版本中即可体验,体验路径:Hello MUI首页–> 列表到详情最佳实践
在开发使用uni-app结合Hello MUI组件库的应用时,实现从列表页跳转到详情页的最佳实践,可以通过Vue Router和组件通信来实现。下面是一个简化的代码案例,展示如何从列表页跳转到详情页,并传递数据。
列表页 (List.vue)
首先,在列表页中,我们创建一个简单的列表,并为每个列表项绑定一个点击事件来跳转到详情页。
<template>
<view>
<mui-list>
<mui-list-item v-for="(item, index) in list" :key="index" @click="navigateToDetail(item)">
{{ item.name }}
</mui-list-item>
</mui-list>
</view>
</template>
<script>
export default {
data() {
return {
list: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
// 更多列表项...
]
};
},
methods: {
navigateToDetail(item) {
uni.navigateTo({
url: `/pages/Detail/Detail?id=${item.id}`
});
}
}
};
</script>
详情页 (Detail.vue)
在详情页中,我们通过onLoad
生命周期函数获取传递过来的参数,并根据参数加载详情数据。
<template>
<view>
<mui-page-header title="详情页" />
<view>
<text>ID: {{ item.id }}</text>
<text>Name: {{ item.name }}</text>
<!-- 更多详情展示... -->
</view>
</view>
</template>
<script>
export default {
data() {
return {
item: {}
};
},
onLoad(options) {
const id = options.id;
// 模拟从服务器获取详情数据(这里简单处理为静态数据)
const mockData = [
{ id: 1, name: 'Item 1 Details' },
{ id: 2, name: 'Item 2 Details' },
// 更多详情数据...
];
this.item = mockData.find(item => item.id === parseInt(id, 10));
}
};
</script>
注意事项
- 路由配置:确保在
pages.json
中正确配置了列表页和详情页的路由。 - 数据传递:在
navigateTo
方法中,通过URL参数传递数据。如果数据量较大或包含复杂结构,可以考虑使用全局状态管理(如Vuex)或存储(如LocalStorage)。 - 错误处理:在实际应用中,应添加错误处理逻辑,如网络请求失败时的提示。
- 性能优化:对于大型列表,考虑使用虚拟列表等技术来优化性能。
通过上述代码案例,可以实现从列表页到详情页的基本跳转和数据传递,同时保持了代码的简洁性和可读性。