UNI-APP 自定义微信小程序底部导航栏
<p>本文只针对于微信小程序的自定义底部导航栏;<br><strong>PS</strong>:可能在进入小程序后,首次点击tabBar会出现闪烁的情况;不能接受的就还是乖乖的用回默认吧!</p>
<h2 id="需求">需求</h2>
<p>在开发记账APP时,感觉微信小程序默认的tabBar功能很简单,而且不能进行美化,作为强迫症的我,不能忍,直接搂它;<br>
我需要达到的效果如下:</p>
<ul>
<li>中间的按钮凸起;</li>
<li>中间的按钮点击时需要跳转二级页面;</li>
</ul>
<p><img src="https://img2022.cnblogs.com/blog/1667295/202205/1667295-20220506101242478-1967635946.png" alt="" loading="lazy"></p>
<h2 id="方案">方案</h2>
<p>当然,我们以UNI-APP官方的案例为主,先看一下官方怎么做的:UNI-APP 自定义 tabBar;<br>
官方文档也是描述了一下,具体实现也还是需要使用wxml、wxss进行实现,并且需要将自定义tabBar放在项目根目录下的custom-tab-bar文件夹下;最终方案也是跳到了微信社区:微信小程序 自定义 tabBar;</p>
<h2 id="实现">实现</h2>
<h3 id="1修改配置pagejson文件">1、修改配置page.json文件</h3>
<p>添加custom字段,并赋值true,表示这里我们使用的是自定义的tabBar;<br>
此时,我们这里的配置数据就不生效了;<br>
<img src="https://img2022.cnblogs.com/blog/1667295/202205/1667295-20220506101258715-2134690294.png" alt="" loading="lazy"></p>
<h3 id="2添加自定义tabbar">2、添加自定义tabBar</h3>
<h4 id="a创建文件夹">a、创建文件夹</h4>
<p>文件包含自定义tabBar:index.js、index.json、index.wxml、index.wxss</p>
<p><img src="https://img2022.cnblogs.com/blog/1667295/202205/1667295-20220506101311143-2079774788.png" alt="" loading="lazy"></p>
<p>针对我上述图中的效果,代码如下:</p>
<h5 id="indexjs">index.js</h5>
<pre><code class="language-javascript">Component({
data: {
selected: 0,
color: "#D1D1D1",
selectedColor: "#A6B1E1",
list: [{
"pagePath": "/pages/index/index",
"text": "账目"
},
{
"pagePath": "/pages/profile/index",
"text": "我的"
}]
},
attached() {
},
methods: {
switchTab(e) {
const data = e.currentTarget.dataset
const url = data.path
wx.switchTab({ url })
this.setData({
selected: data.index,
})
},
// 此处需要针对中间的tabBar跳转到二级页面,而不是使用switchTab
toadd() {
wx.navigateTo({ url: '/pages/bill/edit' })
}
}
})
</code></pre>
<h5 id="indexjson">index.json</h5>
<pre><code class="language-json">{
"component": true
}
</code></pre>
<h5 id="indexwxml">index.wxml</h5>
<pre><code class="language-html"><!--miniprogram/custom-tab-bar/index.wxml-->
<view class="tab-bar">
<view wx:for="{{list}}" wx:key="index" class="tab-bar-item {{item.bulge?'bulge':''}}" data-path="{{item.pagePath}}" data-index="{{index}}" bindtap="switchTab">
<viewwx:if="item.bulge" class="tab-bar-bulge tab-bar-view"></view>
<image style="display: {{item.bulge? 'block' : 'none'}};" class="image" src="{{selected === index ? item.selectedIconPath : item.iconPath}}"></image>
<viewwx:if="{{item.text}}" style="color: {{selected === index ? selectedColor : color}}" class="tab-bar-view">{{item.text}}</view>
</view>
<view class="bulge"bindtap="toadd">
<view class="background">
<image class="image" src="/static/assets/tabbar/plus.png"></image>
</view>
</view>
</view>
</code></pre>
<h5 id="indexwxss">index.wxss</h5>
<pre><code class="language-css">.tab-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 48px;
display: flex;
line-height: 1.2;
padding-bottom: env(safe-area-inset-bottom);
background: white;
}
.tab-bar-item {
flex: 1;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.tab-bar-item .image {
width: 27px;
height: 27px;
}
.bulge {
position: absolute;
left: 50%;
right: 50%;
transform: translate(-50%);
top: -12px;
height: 80px;
width: 60px;
display: flex;
justify-content: center;
}
.bulge .background{
background: #A6B1E1;
width: 45px;
height: 45px;
border-radius: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.bulge .background .image{
width: 20px;
height: 20px;
}
.tab-bar-item .tab-bar-view {
font-size: 13px;
font-weight: bold;
}
</code></pre>
<h3 id="3修改tabbar指向页面">3、修改tabBar指向页面</h3>
<p>实际开发中,如果不进行此项处理则会导致点击tabBar时出现奇怪的问题:点击另外一个bar时,上一个bar才会处于被选中状态;</p>
<p>解决该问题就要在每个tabBar指向页面的onShow添加如下代码:<br>
<strong>PS:网上很多教程都是使用<code>this.$mp.getTabBar</code> 或<code>this.$root.$mp.getTabBar</code>去实现(</strong>uni-app v2.0.0之前应该没事<strong>),但会在热重载tab page时都会报错:<code>Error in onShow hook: "TypeError: Cannot read property 'getTabBar' of undefined"</code>,如下图:</strong><br>
<img src="https://cdn.nlark.com/yuque/0/2022/png/1589422/1651659545257-9672e5d0-cdf0-4487-bee6-62a33daaced8.png#crop=0&crop=0&crop=1&crop=1&from=url&id=sSUr5&margin=%5Bobject%20Object%5D&originHeight=250&originWidth=969&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=" alt="" loading="lazy"><br>
经过一番issue折腾后,最终使用如下实现:</p>
<pre><code class="language-javascript">onShow() {
// 网上很多教程都是使用this.$mp.getTabBar 或 this.$root.$mp.getTabBar去实现
// 但目前的uni-app(2.0.1)版本下会出现undefined的情况,官方的解决方案是使用如下方式
if (typeof this.$scope.getTabBar === 'function' &&
this.$scope.getTabBar()) {
this.$scope.getTabBar().setData({
// 当前页面对应的tab index
selected: 0,
})
}
}
</code></pre>
<p>但是,我们需要优雅点,使用mixins进行混入,达到一个function随处使用,且本文使用的时局部混入,需要在使用到的页面进行混入,代码如下:</p>
<h5 id="构建mixins">构建mixins</h5>
<p>根目录下创建mixins文件夹,并创建tabbar.js</p>
<pre><code class="language-javascript">export const mixin = {
methods: {
setTabBarIndex(index) {
if (typeof this.$scope.getTabBar === 'function' &&
this.$scope.getTabBar()) {
this.$scope.getTabBar().setData({
selected: index,
})
}
}
}
}
</code></pre>
<h5 id="在需要混入的页面进行配置">在需要混入的页面进行配置</h5>
<pre><code class="language-javascript">// 引入混入js
import { mixin } from "@/mixins/tabbar.js";
export default {
mixins: , //混入js文件
onShow() {
this.setTabBarIndex(0);
},
}
</code></pre>
<h3 id="需要注意">需要注意</h3>
<ul>
<li>在UNI-APP编译后,生成了dist文件夹后再进行此项更改,且直接热更新使用的话会出现两个tabBar且重叠的情况,此时需要删除dist,并重新生成;</li>
</ul><br><br>
来源:https://www.cnblogs.com/memoyu/p/16227592.html
頁:
[1]