当前位置: 首页 > news >正文

quickapp_快应用_tabBar

tabBar

      • 配置项中配置tabBar(版本兼容)
      • 使用tabs组件配置tabBar
        • 语法
        • 示例
        • 问题-切换tab没有反应
        • 问题-数据渲染问题
          • 解决
          • 优化
        • 问题-tab的动态配置
      • 第三方组件tabbar

在这里插入图片描述
一般首页都会显示几个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"><!-- if='tabList.length'--><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.indexthis.selectedTab = index}
}
</script>
问题-切换tab没有反应

最初我是直接将tabList写死的,这样tab切换没有问题

init(){
this.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>
问题-数据渲染问题

知识点: 自定义组件生命周期+ 父子组件生命周期执行顺序

前提:以上示例中的四个组件(书城、书架、排行榜、我的)的初始化都是在init生命周期执行的。

问题1:当打开示例中的页面时会同时初始化这四个组件(打开页面时走4个组件的init生命周期函数)。

思考:我就在想要不在页面展现的时候再初始化呢(show生命周期中),经过实践发现自定义组件没有show生命周期。

问题2: 再次打开书城、书架、排行榜、我的页面时存在不更新数据的情况。

原因:[1] 切换tab的时候都是在main页面,不会执行任何生命周期; [2]在主页去其他页面点击左上角返回时走的是main组件的show生命周期,子组件不执行任何生命周期。因此除了通过router跳转到首页外,子组件只初始化一次!

解决

tips: 如果数据量不是很大的话,可以接受在初始化的时候同时初始化4个页面!

若是介意同时加载

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

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

所以我在main页面打开时同时初始化四个页面

在切换tab或者是展示main页面时只重新加载书架的内容(因为书架内容会根据用户行为实时变化)

另外在书城、排行榜、我的页面添加下拉刷新(若是用户想要更新数据可以通过下拉刷新去更新)

  • [1] 组件:在init生命周期中进行初始化,封装一个init方法进行初始化
    onInit(){this.init()
    },
    init(){// 初始化
    }
    
  • [2] 主页:由于书架数据需要每次打开页面都更新
    onShow(){this.refreshBookShelf()
    },
    changeTab(e) {let index = e.index === undefined ? 1 : e.indexthis.selectedTab = indexthis.refreshBookShelf()
    },
    refreshBookShelf(){if (this.selectedTab == 1) {this.$child('bookshelf').init()}
    }
    
问题-tab的动态配置

现在的tab虽然tab-bar中的数据可以动态配置(动态显示tab名字和icon),但是对应的组件是固定的。
在这里插入图片描述
此时可以通过循环判断的方式进行

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

相关文章:

quickapp_快应用_tabBar

tabBar 配置项中配置tabBar(版本兼容)使用tabs组件配置tabBar语法示例问题-切换tab没有反应问题-数据渲染问题解决优化 问题-tab的动态配置 第三方组件tabbar 一般首页都会显示几个tab用于进行页面切换&#xff0c;以下是几种tab配置方式。 配置项中配置tabBar(版本兼容) 在m…...

PCL_点云分割_基于法线微分分割

一、概述 PCL_点云分割_基于法线微分分割_点云法向量微分-CSDN博客 利用不同的半径&#xff08;大的半径、小半径&#xff09;来计算同一个点的法向量差值P。判断P的范围&#xff0c;从而进行分割。 看图理解&#xff1a; 二、计算流程 1、计算P点小半径的法向量Ns 2、计…...

计算机毕业论文内容参考|基于深度学习的交通标识智能识别系统的设计与维护

文章目录 导文摘要前言绪论1课题背景2国内外现状与趋势3课题内容相关技术与方法介绍系统分析总结与展望导文 基于深度学习的交通标识智能识别系统是一种利用深度学习模型对交通标识进行识别和解析的系统。它可以帮助驾驶员更好地理解交通规则和安全提示,同时也可以提高道路交通…...

SELinux零知识学习十六、SELinux策略语言之类型强制(1)

接前一篇文章&#xff1a;SELinux零知识学习十五、SELinux策略语言之客体类别和许可&#xff08;9&#xff09; 二、SELinux策略语言之类型强制 SELinux策略大部分内容都是由多条类型强制规则构成的&#xff0c;这些规则控制被允许的使用权&#xff0c;大多数默认转换标志、审…...

轻量封装WebGPU渲染系统示例<34>-数据驱动之Json构建场景

场景和数据之间的互通&#xff1a; 场景数据化或者数据化场景&#xff0c;是当前的主流场景数据构成方式。方便传输方便交换甚至是交互。 内置数据互通机制更有利于用户在各种应用场合下实现具体的3D相关的应用需求。用户只需要关心标准的或者约定好的数据定义及操作方式就能方…...

全局异常拦截和Spring Security认证异常的拦截的顺序

&#x1f4d1;前言 本文主要全局异常拦截和Spring Security认证异常的顺序&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日…...

Hive Lateral View explode列为空时导致数据异常丢失

一、问题描述 日常工作中我们经常会遇到一些非结构化数据&#xff0c;因此常常会将Lateral View 结合explode使用&#xff0c;达到将非结构化数据转化成结构化数据的目的&#xff0c;但是该方法对应explode的内容是有非null限制的&#xff0c;否则就有可能造成数据缺失。 SE…...

音频类型转换工具-可执行文件exe/dmg制作

朋友车载音乐需要MP3格式&#xff0c;想要个批量转换工具 准备工作 brew install ffmpeg --HEAD或者官网下载安装ffmpeg并配置环境conda install ffmpeg 或者pip install ffmpeg-python 音频类型转换程序.py文件 exe文件在windows下打包&#xff0c;dmg在macos下打包&#…...

【Proteus仿真】【51单片机】公交车报站系统

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用LCD12864显示模块、DS18B20温度传感器、DS1302时钟模块、按键、LED蜂鸣器、ULN2003、28BYJ48步进电机模块等。 主要功能&#xff1a; 系统运行后&…...

C++--STL总结

参考教程&#xff1a;黑马程序员匠心之作|C教程从0到1入门编程,学习编程不再难_哔哩哔哩_bilibili 软件界一直希望建立一种可重复利用的东西&#xff0c;C的面向对象和泛型编程思想&#xff0c;目的就是复用性的提升。 大多情况下&#xff0c;数据结构和算法都未能有一套标准,…...

Python----图像的手绘效果

图像的数组表示 图像是有规则的二维数据&#xff0c;可以用numpy 库将图像转换成数组对象 : from PIL import Image import numpy as np imnp.array(Image.open("D://np.jpg")) print(im.shape,im.dtype)结果&#xff1a; 图像转换对应的ndarray 类型是3 维数据&am…...

Android13集成paho.mqtt.android启动异常

项目中原依赖是&#xff1a; implementation(org.eclipse.paho:org.eclipse.paho.android.service:1.1.1) {exclude module: support-v4transitive true } implementation org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5在Android10系统运行正常&#xff0c;能够连接…...

STM框架之按键扫描新思路

STM框架之按键扫描新思路 引入代码展示思路分析 我们学习了定时器实现毫秒级/秒级任务框架&#xff0c;这期我们基于任务框架学习按键扫描新思路。 引入 在按键扫描的过程中&#xff0c;最重要的一步就是按键消抖&#xff0c;解决的方法最简单粗暴的就是先扫描一次按键状态&am…...

Linux服务器挂载另一台服务器的文件夹(mount)

我们实际应用中&#xff0c;会常遇到多个Linux服务器之间需要频繁共享文件&#xff0c;或者是一台服务器需要使用另一台服务器的闲置磁盘空间。最方便的方法就是挂载另一台linux文件夹&#xff08;文件服务器&#xff09;&#xff0c;通俗理解为&#xff1a;当前服务器远程连接…...

剑指offer --- 用两个栈实现队列的先进先出特性

目录 前言 一、读懂题目 二、思路分析 三、代码呈现 总结 前言 当我们需要实现队列的先进先出特性时&#xff0c;可以使用栈来模拟队列的行为。本文将介绍如何使用两个栈来实现队列&#xff0c;并给出具体的思路和代码实现。 一、读懂题目 题目&#xff1a;用两个栈实现一…...

流媒体协议

◆ RTP(Real-time Transport Protocol)&#xff0c;实时传输协议。 ◆ RTCP(Real-time Transport Control Protocol)&#xff0c;实时传输控制协议。 ◆ RTSP(Real Time Streaming Protocol)&#xff0c;实时流协议。 ◆ RTMP(Real Time Messaging Protocol)&#xff0c;实时…...

ClickHouse的分片和副本

1.副本 副本的目的主要是保障数据的高可用性&#xff0c;即使一台ClickHouse节点宕机&#xff0c;那么也可以从其他服务器获得相同的数据。 Data Replication | ClickHouse Docs 1.1 副本写入流程 1.2 配置步骤 &#xff08;1&#xff09;启动zookeeper集群 &#xff08;2&…...

C语言编程陷阱(五)

陷阱21:不要使用逗号运算符代替分号 C语言中,我们可以使用分号来结束一个语句,比如a = b;,这样可以让编译器知道语句的边界,以及执行的顺序。但是,如果我们想要在一个语句中执行多个表达式,就可以使用逗号运算符,比如a = (b = c, c + 1);,这样可以让编译器按照从左到右…...

chardet检测文件编码,使用生成器逐行读取文件

detect_encoding 函数使用 chardet 来检测文件的编码。然后&#xff0c;在 process_large_file 函数中&#xff0c;根据检测到的编码方式打开文件。这样&#xff0c;你就能够更准确地处理不同编码的文件。 import chardetdef detect_encoding(file_path):with open(file_path,…...

html所有标签和DOCTYPE的总结

一、DOCTYPE 1. 意义 DOCTYPE是一种标准通用标记语言的文档类型声明&#xff0c;告诉标准通用标记语言解析器它应该使用什么样的文档类型定义来解析文档。 2. 应用 现在&#xff0c;我们需要告诉标准通用标记语言解析器&#xff0c;我们接下去要用html来编写代码了。 <…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

TCP/IP 网络编程 | 服务端 客户端的封装

设计模式 文章目录 设计模式一、socket.h 接口&#xff08;interface&#xff09;二、socket.cpp 实现&#xff08;implementation&#xff09;三、server.cpp 使用封装&#xff08;main 函数&#xff09;四、client.cpp 使用封装&#xff08;main 函数&#xff09;五、退出方法…...

算法—栈系列

一&#xff1a;删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...