专栏首页极乐技术社区实战教程 | 小程序自定义TabBar 如何实现“keep-alive”

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

自定义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)

}

}

},

})

效果预览

极乐技术社区

本文分享自微信公众号 - 极乐技术社区(wxapp-union),作者:陇锦

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-06-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微信小程序自定义 tabBar 踩坑实践

    创建一个与 /pages 的同级目录,命名为 /custom-tab-bar,注意目录层级与目录命名问题,不可用其他名称命名。

    江不知
  • 《手把手带你学爬虫──初级篇》第2课 Requests库讲解

    Requests是一常用的http请求库,它使用python语言编写,可以方便地发送http请求,以及方便地处理响应结果。

    GitOPEN
  • 手把手教你入门AIoT(8)

    本课程会深入浅出地介绍 MQTT 协议的各种特性,对每个协议特性都辅以具体代码进行讲解,并通过一个 IoT+AI 项目实战来具体展现 MQTT 在移动端、Web...

    刘盼
  • 《手把手带你学爬虫──初级篇》第2课 Requests库讲解

    Requests是一常用的http请求库,它使用python语言编写,可以方便地发送http请求,以及方便地处理响应结果。

    GitOPEN
  • 使用原生开发高仿瑞幸小程序(一):使用 Vant 组件库和配置多页面

    为什么要跨平台,自然是为了节约成本。尤其是创业初期,需要快速迭代,快速试错。此时用原生技术,开发起来未免太过拖沓。我所想的是,如何能够快速的,最大化的覆盖屏幕数...

    一只图雀
  • 实战 | 0~1 自定义组件开发问卷小程序

    本文将帮助您基于腾讯云微搭低代码 WeDa 平台,从0到1快速打造如下图所示的问卷调查小程序。

    腾讯云开发TCB
  • 『React Navigation 3x系列教程』createBottomTabNavigator开发指南

    createBottomTabNavigator 相当于iOS里面的TabBarController,屏幕下方的标签栏。如图:

    CrazyCodeBoy
  • 一些笔记20200714

    this.$once('hook:beforeDestroy', function () { picker.destroy() }):

    wade
  • 小程序-实现自定义动画弹框/提示框

    在小程序中,用户与界面进行交互时,有一些用户反馈提示,例如:触发某个按钮,从底部弹出框,从顶部弹出等

    itclanCoder
  • 小程序-实现自定义组件以及自定义组件间的通信

    对于组件的封装,在小程序当中对于多个页面的复用有着重要的作用,小程序中注册的每个页面都是独立的

    itclanCoder
  • 彻底揭秘keep-alive原理

    用户在某个列表页面选择筛选条件过滤出一份数据列表,由列表页面进入数据详情页面,再返回该列表页面,我们希望:列表页面可以保留用户的筛选(或选中)状态。keep-a...

    前端黑板报
  • 详解HTTP 与TCP中Keep-Alive机制的区别

    keepalive已经不是什么新鲜的概念了,HTTP协议中有keep-alive的概念,TCP协议中也有keep-alive的概念。二者的作用是不同的。本文将详...

    田守枝
  • 从项目实际问题引发的思考

    现在有一个 Web 项目,前端是使用 Vue.js 开发的,整个前端需要部署到 K8S 上,后端和前端分开,同样也需要部署到 K8S 上,因此二者需要打包为 D...

    崔庆才
  • vue面试题+答案,2021前端面试

    MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范

    it优课
  • 小程序搜索栏新增“搜索历史” | 微信iOS版更新至6.6.0 ,客户端大更新、公众号界面、后台改版

    轻松一刻 ? 漫画来自于西乔《神秘的程序员们》 01 小程序搜索栏新增“搜索历史” 近期,极乐叔发现微信中出现了小程序历史搜索,在小程序发现栏中点击小程序搜索框...

    极乐君
  • 【RL-TCPnet网络教程】第20章 RL-TCPnet之BSD Socket客户端

    本章节为大家讲解RL-TCPnet的BSD Socket,学习本章节前,务必要优先学习第18章的Socket基础知识。有了这些基础知识之后,再搞本章节会有事半功...

    armfly
  • 一杯茶的时间,上手 Taro 京东小程序开发

    小程序世界纷争不断,巨型 App 都在纷纷构建自己的小程序流量入口,希望在造福商家、用户的同时,也能巩固自家流量壁垒,我们已经熟知了微信小程序、支付宝小程序,我...

    一只图雀
  • 【面试说】一年半前端 Bigo 一二三 面

    笔者其实是三月份就面的 Bigo,当时工作经验算一年半多。之所以现在才发,其实是之前虽然总结了,但多半是自己总结归纳复盘用,有点粗糙,现在重新整理,希望对大家有...

    GopalFeng
  • 实操 Web Cache

    实操 Web Cache 摘要 写这篇文章的原因,是我看到网上很多谈这类的文章,多是人云亦云,不求实事,误导读者。 下面文中我会一个一个做实验,并展示给你,说明...

    netkiller old

扫码关注云+社区

领取腾讯云代金券