当前位置: 代码网 > it编程>游戏开发>ar > quickapp_快应用_tabBar

quickapp_快应用_tabBar

2024年08月03日 ar 我要评论
如上:自定义组件只有3个三个生命周期函数。

在这里插入图片描述
一般首页都会显示几个tab用于进行页面切换,以下是几种tab配置方式。

配置项中配置tabbar(版本兼容)

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": "我的"
          }]
      }
}

但是此时存在以下两个问题

  • [1] tabbar配置项是在1110+版本适用,在低于1110版本中不起作用。
    (目前绝大部分机型版本为1070+),还有很多手机型号不兼容!
  • [2] tab不能动态配置!

使用tabs组件配置tabbar

语法
  • 概括

    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>
问题-切换tab没有反应

最初我是直接将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: 再次打开书城、书架、排行榜、我的页面时存在不更新数据的情况。

因此在切换tab的时候其实并没有切换页面,所以数据也就不会更新了!

解决

若是介意同时加载

  • [1]自定义组件中:不在init生命周期中进行初始化,封装一个init方法进行初始化
    init(){
      // 初始化
    }
    
  • [2] 主页中:在ready生命周期默认初始化第一个组件
    onready(){
      this.$child('library').init()
    }
    
    每次展示页面和切换tab时加载对应组件
    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()
      }
    }
    
优化

在这个需求里面书城、排行榜、我的页面的数据不是经常更新,所以

  • [1]在main页面打开时同时初始化四个页面(只有打开页面时加载—相当于页面缓存)
  • [2]在书城、排行榜、我的页面添加下拉刷新(若是用户想要更新数据可以通过下拉刷新去更新)

而书架的内容会根据用户行为实时变化,所以在切换tab或者是展示main页面时需要重新加载

  • [1] 组件:在init生命周期中进行初始化,封装一个init方法进行初始化
    oninit(){
      this.init()
    },
    init(){
      // 初始化
    }
    
  • [2] 主页:由于书架数据需要每次打开页面都更新
    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虽然tab-bar中的数据是在后端获取(动态配置),但是对应的组件是固定的。
在这里插入图片描述
以上代码中无论tab-bar中第一个元素的文本显示书城、书架还是我的,切换时显示的永远是书城的内容!

此时可以通过循环判断的方式进行

<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组件

本质就是将tabbar固定定位在底部,每次切换tab时清除除此页面外的其他页面

router.push({
  uri: path,
  params: {
    ___param_launch_flag___: 'cleartask'
  }
})
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com