前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实战教程 | 小程序自定义TabBar 如何实现“keep-alive”

实战教程 | 小程序自定义TabBar 如何实现“keep-alive”

作者头像
极乐君
发布2021-07-05 15:11:00
9790
发布2021-07-05 15:11:00
举报
文章被收录于专栏:极乐技术社区极乐技术社区

自定义TabBar方案

我们可以新建一个home文件夹,在home/index.wxml中写一个tabBar,然后把TabBar页面写成组件,然后点击TabBar切换相应的组件展示就可以。代码如下:

wxml部分

<!-- home页面 -->

<view id='index'>

<!-- 自定义头部 -->

<head name='{{name}}' bgshow="{{bgshow}}" backShow='false'></head>

<!-- 首页 -->

<index change='{{activeIndex==0}}'></index>

<!-- 购物车 -->

<cart change='{{activeIndex==1}}'></cart>

<!-- 订单 -->

<order change='{{activeIndex==2}}'></order>

<!-- 我的 -->

<my change='{{activeIndex==2}}'></my>

<!-- tabbar -->

<view class="tab ios">

<view class="items {{activeIndex==index?'active':''}}" wx:for="{{tab}}" bindtap="choose" data-index='{{index}}' wx:key='index' wx:for-item="items">

<image wx:if="{{activeIndex==index}}" src="{{items.activeImage}}"></image>

<image wx:else src="{{items.image}}"></image>

<text>{{items.name}}</text>

</view>

</view>

</view>

home页面的ts

Page({

data: {

activeIndex:0,

tab:[

{

name:'商品',

image:'../../images/index.png',

activeImage:'../../images/index-hover.png',

},

{

name:'购物车',

image:'../../images/cart.png',

activeImage:'../../images/cart-hover.png',

},

{

name:'订单',

image:'../../images/order.png',

activeImage:'../../images/order-hover.png',

},

{

name:'我的',

image:'../../images/my.png',

activeImage:'../../images/my-hover.png',

}

]

},

// 切换事件

choose(e:any){

const _this=this;

const {activeIndex}=_this.data;

if(e.currentTarget.dataset.index==activeIndex){

return

}else{

_this.setData({

activeIndex:e.currentTarget.dataset.index

})

}

},

})

上面代码不难理解,点击以后改变activeIndex从而控制每个组件的渲染和销毁,这样付出的代价还是比较大的,需要我们进一步的优化。

如何实现keep-alive

我们知道,这里主要是避免组件反复创建和渲染,有效提升系统性能。

实现思路

  1. 在tab每个选项增加两个值:status和show,show控制组件是否需要渲染,status控制组件display
  2. 初始化时候设置首页的status和show,其他都为false
  3. 当我们切换时:把上一个tab页面的status改为false,然后把当前要切换页面的tab数据中的status和show都改为true,最后再更新一下activeIndex的值。

wxml代码:

<!-- 首页 -->

<view wx:if="{{tab[0].show}}" hidden="{{!tab[0].status}}">

<index></index>

</view>

<!-- 购物车 -->

<view wx:if="{{tab[1].show}}" hidden="{{!tab[1].status}}">

<cart></cart>

</view>

<!-- 订单 -->

<view wx:if="{{tab[2].show}}" hidden="{{!tab[2].status}}">

<order></order>

</view>

<!-- 我的 -->

<view wx:if="{{tab[3].show}}" hidden="{{!tab[3].status}}">

<my></my>

</view>

ts代码

Page({

data: {

activeIndex:0, //当前选中的index

tab:[

{

name:'商品',

image:'../../images/index.png',

activeImage:'../../images/index-hover.png',

status:true,//控制组件的display

show:true, //控制组件是否被渲染

},

{

name:'购物车',

image:'../../images/cart.png',

activeImage:'../../images/cart-hover.png',

status:false,

show:false,

},

{

name:'订单',

image:'../../images/order.png',

activeImage:'../../images/order-hover.png',

status:false,

show:false,

},

{

name:'我的',

image:'../../images/my.png',

activeImage:'../../images/my-hover.png',

status:false,

show:false,

}

]

},

choose(e:any){

const _this=this;

const {activeIndex}=_this.data;

//如果点击的选项是当前选中,就不执行

if(e.currentTarget.dataset.index==activeIndex){

return

}else{

//修改上一个tab页面的status

let prev='tab['+activeIndex+'].status',

//修改当前选中元素的status

status='tab['+e.currentTarget.dataset.index+'].status',

//修改当前选中元素的show

show='tab['+e.currentTarget.dataset.index+'].show';

_this.setData({

[prev]:false,

[status]:true,

[show]:true,

activeIndex:e.currentTarget.dataset.index,//更新activeIndex

})

}

},

})

这样基本就大功告成了,来看一下效果:

当我们点击切换时候,如果当前组件没有渲染就会进行渲染,如果渲染过后进行切换只是改变display,完美实现了需求,大功告成!

实际业务场景分析

在实际使用中还有两种种情况:

  • 情况1:比如某些数据并不希望他首次加载后就数据保持不变,当切换页面时候希望数据进行更新,比如笔者做的电商小程序,在首页点击商品加入购物车,然后切换到购物车,每次切换时候肯定需要再次进行请求。
  • 情况2:像个人中心这种页面,数据基本请求一次就可以,没必要每次切换请求数据,这种我们不需要进行改进。

我们给组件传递一个值:status,然后在组件中监听这个值的变化,当值为true时候,去请求接口更新数据。具体代码如下:

wxml代码(只列举关键部分):

<!-- 首页 -->

<view wx:if="{{tab[0].show}}" hidden="{{!tab[0].status}}">

<index change='{{tab[0].status}}'></index>

</view>

<!-- 购物车 -->

<view wx:if="{{tab[1].show}}" hidden="{{!tab[1].status}}">

<cart change='{{tab[0].status}}'></cart>

</view>

首页组件/购物车组件ts代码:

Component({

/**

* 组件的属性列表

*/

properties: {

change: {

type: String,//类型

value: ''//默认值

},

},

observers: {

//监听数据改变进行某种操作

'change': function(change) {

if(change=='true'){

console.log('更新首页数据'+change)

}

}

},

})

效果预览

极乐技术社区

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 极乐技术社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档