How to implement “keep-alive” in TabBar

After writing a small program to implement creative animation and small program development skills of TabBar, some friends ask that the custom TabBar can do a lot of interaction, but click to switch TabBar page, will be followed by the destruction and reconstruction of components, this does affect the performance. Here is a solution to “keep-alive”. If there is a better plan, welcome to comment section exchange. Welcome to like and bookmark ~

This is the first day of my participation in the Gwen Challenge

Custom TabBar schemes

Although mentioned in the previous article, the componentized implementation is adopted this time, and the specific implementation is as follows:

  • We can create a new home folder, write a tabBar in home/index.wxml, write the tabBar page as a component, and then click tabBar to switch to the corresponding component display. The code is as follows:

  • WXML part

<! -- Home page -->

<view id='index'>
  <! -- Custom header -->
  <head name='{{name}}' bgshow="{{bgshow}}" backShow='false'></head>

    <! - home page - >
    <index change='{{activeIndex==0}}'></index>
    <! -- Shopping cart -->
    <cart change='{{activeIndex==1}}'></cart>
     <! Order -- - >
    <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>

Copy the code
  • Ts for the home page
Page({
  data: {
    activeIndex:0.tab:[
      {
        name:'goods'.image:'.. /.. /images/index.png'.activeImage:'.. /.. /images/index-hover.png'}, {name:'Shopping cart'.image:'.. /.. /images/cart.png'.activeImage:'.. /.. /images/cart-hover.png'}, {name:'order'.image:'.. /.. /images/order.png'.activeImage:'.. /.. /images/order-hover.png'}, {name:'I'.image:'.. /.. /images/my.png'.activeImage:'.. /.. /images/my-hover.png',}},// Switch events
  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
        })
    }
  },
})

Copy the code
  • The above code is not difficult to understand, click to changeactiveIndexTo control the rendering and destruction of each component, the cost is still relatively large, which requires further optimization.

How to implement keep-alive

As we know, the main point here is to avoid repetitive component creation and rendering, which can improve system performance.

Implementation approach

  • 1. Add two values to each TAB option: status and show. Show controls whether the component needs to render, and status controls display

  • 2. Set status and show on the home page to false during initialization

  • 3. When we switch: change the status of the previous TAB to false, change the status and show values of the current TAB to true, and update the activeIndex value.

  • WXML code:

    <! - home page - >
    <view wx:if="{{tab[0].show}}" hidden="{{! tab[0].status}}">
        <index></index>
    </view>
    <! -- Shopping cart -->
    <view wx:if="{{tab[1].show}}"  hidden="{{! tab[1].status}}">
        <cart></cart>
    </view>
    <! Order -- - >
    <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>
Copy the code
  • Ts code
Page({
  data: {
    activeIndex:0.// The currently selected index
    tab:[
      {
        name:'goods'.image:'.. /.. /images/index.png'.activeImage:'.. /.. /images/index-hover.png'.status:true.// Control the component's display
        show:true.// Controls whether the component is rendered
      },
      {
        name:'Shopping cart'.image:'.. /.. /images/cart.png'.activeImage:'.. /.. /images/cart-hover.png'.status:false.show:false}, {name:'order'.image:'.. /.. /images/order.png'.activeImage:'.. /.. /images/order-hover.png'.status:false.show:false}, {name:'I'.image:'.. /.. /images/my.png'.activeImage:'.. /.. /images/my-hover.png'.status:false.show:false,}},choose(e:any){
    const _this=this;
    const {activeIndex}=_this.data;
    // If the selected option is currently selected, it will not be executed
    if(e.currentTarget.dataset.index==activeIndex){
      return
    }else{
       // Change the status of the previous TAB page
       let prev='tab['+activeIndex+'].status'.// Change the status of the currently selected element
           status='tab['+e.currentTarget.dataset.index+'].status'.// Modify show for the currently selected element
           show='tab['+e.currentTarget.dataset.index+'].show';
      
        _this.setData({
          [prev]:false,
          [status]:true,
          [show]:true.activeIndex:e.currentTarget.dataset.index,/ / update the activeIndex})}}})Copy the code
  • That’s basically it. Here’s the result:

  • When we click switch, if the current component is not rendered it will be rendered, and if we switch after rendering it will just changedisplay, perfect realization of the demand, done!

Analyze actual service scenarios

In practice, there are two other cases:

Case 1: For example, some data are not expected to remain unchanged after loading for the first time, and they are expected to be updated when switching pages. For example, the author made an e-commerce mini program, which clicked goods on the home page to add to the shopping cart and then switched to the shopping cart. Case 2: For pages like the personal center, the basic data request is ok once, there is no need to switch the data request every time, we do not need to improve this.

  • We pass a value to the component: status, and then listen for that value in the component and, when true, ask the interface to update the data. The specific code is as follows:

  • WXML code (to list only the key parts) :

<! - home page - >
 <view wx:if="{{tab[0].show}}" hidden="{{! tab[0].status}}">
    <index change='{{tab[0].status}}'></index>
 </view>

<! -- Shopping cart -->
 <view wx:if="{{tab[1].show}}"  hidden="{{! tab[1].status}}">
  <cart change='{{tab[0].status}}'></cart>
 </view>
Copy the code
  • Home page component/shopping cart componenttsCode:
Component({
  /** * Component property list */
  properties: {
    change: {
      type: String./ / type
      value: ' '/ / the default value}},observers: {
    // Listen for data changes to perform some kind of operation
    'change': function(change) {
      if(change=='true') {console.log('Update home page data'+change)
      }
    }
  },
})
Copy the code
  • Take a look at the end result:

At the end

At present can think of the implementation method is like this, if you have a better way, welcome to comment section exchange, if there is an error in the article, welcome to correct. 👉 focus on front-end 365: share front-end tips and some problems in the development process, welcome to follow + favorites + likes, thank you for your support ~