赞
踩
一般首页都会显示几个tab用于进行页面切换,以下是几种tab配置方式。
在manifest.json配置文件中display.tabBar可以进行tab配置,如下
{
"display": {
"tabBar": {
"color": "#000000", //文字颜色
"selectedColor": "#008000", //选中文字颜色
"tabbarBackgroundColor": "#FFFFFF", //组件背景
"list": [{
"pagePath": "/home", //页面路由路径
"pageParams":"{test: 'test1'}" , //页面参数
"iconPath": "/Common/home.png", //图标
"selectedIconPath": "/Common/home_active.png", //选中图标
"text": "首页" //文字内容
},
{
"pagePath": "/mine",
"pageParams":"{test: 'test2'}",
"iconPath": "/Common/mine.png",
"selectedIconPath": "/Common/mine_active.png",
"text": "我的"
}]
}
}
但是此时存在以下两个问题
1110+
版本适用,在低于1110版本中不起作用。概括
tabs组件:仅支持最多一个tab-bar组件和最多一个tab-content组件。
tab-bar组件: tabs的标签展示区,子组件排列方式为横向排列。
tab-content组件:tabs的内容展示区,高度默认充满 tabs 剩余空间,子组件排列方式为横向排列。
<!-- 书城 -->
<import name="library" src="../../components/library"></import>
<!-- 书架 -->
<import name="bookshelf" src="../../components/bookshelf"></import>
<!-- 排行榜 -->
<import name="ranking" src="../../components/bookshelf/ranking.ux"></import>
<!-- 我的 -->
<import name="mine" src="../../components/mine"></import>
<template>
<div class="page-wrapper">
<tabs index="{{selectedTab}}" onchange="changeTab" >
<tab-content>
<library></library>
<bookshelf id='bookshelf'></bookshelf>
<ranking ></ranking>
<mine></mine>
</tab-content>
<tab-bar mode="fixed" class="tab-bar">
<div class="tab-item" for="tabList">
<image class="iconfont" src='{{ selectedTab === $idx ? $item.onfocus_icon_url : $item.icon_url}}'></image>
<text class="tab-title">{{ $item.title }}</text>
</div>
</tab-bar>
</tabs>
</div>
</template>
<script>
export default {
private: {
tabList: [],
selectedTab: 0 //默认第一个页面
},
onInit() {
this.init()
},
init (){
this.tabList = [
{
title: '书城',
icon_url: 'https://img.iwave.net.cn/other/c7d4037ba99fea69c46dc096f46b11b6.png',
onfocus_icon_url: 'https://img.iwave.net.cn/other/c996112028a8de365b292d7fcc95ebc2.png',
type: 0
},
{
title: '书架',
icon_url: 'https://img.iwave.net.cn/other/6862b4ec95abc6f6f40494f67a6fae0d.png',
onfocus_icon_url: 'https://img.iwave.net.cn/other/23512e7e0b47bbaf0d2a86f7dfb1c986.png',
type: 1
},
{
title: '排行榜',
icon_url: 'https://img.iwave.net.cn/other/64f89f4184c04f20143c49c0685659c1.png',
onfocus_icon_url: 'https://img.iwave.net.cn/other/d5b9e41090cdbbc1d92dae91f2d4398b.png',
type: 2
},
{
title: '我的',
icon_url: 'https://img.iwave.net.cn/other/f6e7f3684b50f041f00e88c0753466c0.png',
onfocus_icon_url: 'https://img.iwave.net.cn/other/2e72f98dc9780b08cd00f684f2ca2c21.png',
type: 3
}
]
},
changeTab(e) {
let index = e.index === undefined ? 1 : e.index
this.selectedTab = index
}
}
</script>
最初我是直接将tabList写死的(如下),这样tab切换没有问题
init(){
this.tabList = [...]
}
后来tabList在后端获取数据进行配置,从后端获取数据,发现tab切换没有反应
init(){
const res = await $http.httpGet('init')
if (res && !res.status) {
this.tabList = res.data.tabs
}
}
这是为什么呢?
原因是因为tab组件的子组件tab-bar、tab-content中的数据是不允许动态变换的
!若是动态加载需要在加载完成时再渲染
,也就是加上if判断
<tabs index="{{selectedTab}}" onchange="changeTab" if='tabList.length'>
...
</tabs>
经过上述处理之后tab组件的切换就没有问题了!
前提:以上示例中的四个组件(书城、书架、排行榜、我的)的初始化都是在当前组件的init生命周期执行的。
这4个tab页面现在被做成一个页面(引入了4个组件),而父子组件初始化如下
父onInit-> 子onInit -> 子onReady -> 父onReady -> 父onShow
虽然在表面看起来这是4个页面(但是实际上是1个页面中的四个组件),因此在项目打开的时候这4个页面/组件会同时初始化(多接口调用)
问题2: 再次打开书城、书架、排行榜、我的页面时存在不更新数据的情况。
tips:引入的四个子组件虽然表面看起来只展示了一个,但是实际是展示了4个(只不过3个被溢出隐藏了)!
因此在切换tab的时候其实并没有切换页面,所以数据也就不会更新了!
tips: 如果数据量不是很大的话,可以接受在初始化的时候同时初始化4个页面!
若是介意同时加载
init(){
// 初始化
}
onReady(){
this.$child('library').init()
}
onShow(){
this.refreshBookShelf()
},
changeTab(e) {
let index = e.index === undefined ? 1 : e.index
this.selectedTab = index
this.refreshBookShelf()
},
refreshBookShelf(){
if (this.selectedTab == 0) {
this.$child('library').init()
}
if (this.selectedTab == 1) {
this.$child('bookshelf').init()
}
if (this.selectedTab == 2) {
this.$child('ranking').init()
}
if (this.selectedTab == 3) {
this.$child('mine').init()
}
}
在这个需求里面书城、排行榜、我的页面的数据不是经常更新,所以
而书架的内容会根据用户行为实时变化,所以在切换tab或者是展示main页面时需要重新加载
onInit(){
this.init()
},
init(){
// 初始化
}
onShow(){
this.refreshBookShelf()
},
changeTab(e) {
let index = e.index === undefined ? 1 : e.index
this.selectedTab = index
this.refreshBookShelf()
},
refreshBookShelf(){
if (this.selectedTab == 1) {
this.$child('bookshelf').init()
}
}
现在的tab虽然tab-bar中的数据是在后端获取(动态配置),但是对应的组件是固定的。
以上代码中无论tab-bar中第一个元素的文本显示书城、书架还是我的,切换时显示的永远是书城的内容!
此时可以通过循环判断的方式进行
通过tab-bar配置的type固定是哪个组件进行渲染
<block for='item in tabList'>
<library if='item.type == 0'></library>
<bookshelf if='item.type == 1' id='bookshelf'></bookshelf>
<ranking if='item.type == 2'></ranking>
<mine if='item.type == 3'></mine>
</block>
注意: 只能通过if判断是否展示组件!!!!
使用三元表达式和&&判断不起效果!!!!
<block for='item in tabList'>
{{
(
item.type == 0 ? <library></library> : (
item.type == 1 ? <bookshelf id='bookshelf'></bookshelf> : (
item.type == 2 ? <ranking></ranking> : <mine></mine>
)))
}}
</block>
此时会在tab-content中渲染16个组件!!!
相当于是不管判断成不成立,每次循环都渲染4个组件!!!
另外就是其他页面跳转到main页面时传递的selectedTab值必须与type对应!
比如跳转到排行版页面
const index = this.tabList.findIndex(item => item.type == 2)
router.push('/page/main',{
selectedTab: index
})
直接使用第三方组件库的tabbar组件
本质就是将tabbar固定定位在底部,每次切换tab时清除除此页面外的其他页面
router.push({
uri: path,
params: {
___PARAM_LAUNCH_FLAG___: 'clearTask'
}
})
tips:
推荐使用tabbar组件进行tab配置,因为可以将4个页面隔离开来!
若是使用tabs组件配置tabBar会增加组件之间的耦合性!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。