Aunque WeChat Mini Program ofrece una barra de navegación nativa a través de la configuración en app.json, esta presenta limitaciones significativas cuando se requiere un alto grado de dinamismo, como el cambio en tiempo real de temas (colores de texto, fondos o iconos) que la API estándar wx.setTabBarItem no permite gestionar de forma integral.
Para superar estas restricciones, una solución robusta consiste en implementar una TabBar basada en plantillas (templates). Esto permite un control total sobre el renderizado y el estado de la navegación.
1. Definición de la Estructura (WXML)
Primero, creamos un archivo de plantilla llamado nav-template.wxml. Esta estructura utiliza un componente de navegación que reacciona a los datos globales del sistema.
<template name="customTabBar">
<view class="nav-container" style="background: {{navConfig.backgroundColor}}; border-top: 1px solid {{navConfig.borderColor || '#eee'}}; bottom: 0;">
<block wx:for="{{navConfig.items}}" wx:key="url">
<navigator
url="{{item.isSelected ? '' : item.url}}"
open-type="reLaunch"
hover-class="none"
class="nav-item">
<image
class="nav-icon"
src="{{item.isSelected ? item.activeIcon : item.defaultIcon}}">
</image>
<text style="color: {{item.isSelected ? navConfig.selectedTextColor : navConfig.defaultTextColor}}">
{{item.label}}
</text>
</navigator>
</block>
</view>
</template>
2. Estilos Globales (WXSS)
En el archivo app.wxss, definimos el comportamiento visual para asegurar que la barra se mantenga fija en la parte inferior y distribuya los elementos proporcionalmente.
.nav-container {
position: fixed;
display: flex;
width: 100%;
height: 110rpx;
z-index: 1000;
box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.05);
}
.nav-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 20rpx;
}
.nav-icon {
width: 54rpx;
height: 54rpx;
margin-bottom: 4rpx;
}
3. Gestión de Datos en app.js
Centralizamos la configuración en el objeto global del proyecto. El método syncTabBarState se encargará de identificar la ruta actual y marcar el elemento activo.
App({
globalData: {
tabBarConfig: {
defaultTextColor: "#8a8a8a",
selectedTextColor: "#1296db",
backgroundColor: "#ffffff",
borderColor: "#dcdcdc",
items: [
{
url: "/pages/home/index",
label: "Inicio",
defaultIcon: "/assets/home.png",
activeIcon: "/assets/home-active.png"
},
{
url: "/pages/profile/index",
label: "Perfil",
defaultIcon: "/assets/user.png",
activeIcon: "/assets/user-active.png"
}
]
}
},
updateTabBar: function() {
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
const currentRoute = `/${currentPage.route}`;
const config = this.globalData.tabBarConfig;
config.items = config.items.map(item => ({
...item,
isSelected: item.url === currentRoute
}));
currentPage.setData({
navData: config
});
}
});
4. Integración en las Páginas
Para que la barra aparezca en una vista específica (por ejemplo, home.wxml), importamos la plantilla y pasamos los datos procesados.
<!-- home.wxml -->
<import src="../../templates/nav-template.wxml" />
<view class="main-content">
<!-- Contenido de la página -->
</view>
<template is="customTabBar" data="{{navConfig: navData}}" />
Finalmente, invocamos la lógica de actualización en el ciclo de vida onShow o onLoad de cada página involucrada:
// home.js
const app = getApp();
Page({
onShow: function() {
app.updateTabBar();
}
});
Este enfoque permite modiifcar dinámicamente cualquier propiedad de la TabBar, incluyendo colores de texto y rutas, simplemente actualizando el objeto globalData y llamando nuevamente a la función de sincronización, lo cual es ideal para aplicaciones que implementan "Modo Oscuro" o personalización por parte del usuario.