uniapp自定义tabbar(效果和原生小程序一样,而且底部导航可以超过5个)
首先讲原理:通过引入其他页面到本页里,类似html中的iframe也可以理解为ajax的异步加载html,至此就可以达到底部不会闪烁的问题(自定义vue组件跳转会闪烁,狗眼闪瞎…)1.用到一个插件,方便快捷,大小为6.5KB.,链接为https://ext.dcloud.net.cn/plugin?id=4124导入的时候遇到一个坑,它会把原来的node_modues替换掉…导入的时候可以先备份一
·
首先讲原理:通过引入其他页面到本页里,类似html中的iframe也可以理解为ajax的异步加载html,至此就可以达到底部不会闪烁的问题(自定义vue组件跳转会闪烁,狗眼闪瞎…)
1.用到一个插件,方便快捷,大小为6.5KB.,链接为https://ext.dcloud.net.cn/plugin?id=4124
导入的时候遇到一个坑,它会把原来的node_modues替换掉…导入的时候可以先备份一下,然后综合一下更新到node_modues
2.导入插件后,npm 安装引入npm install uni-lb-tabbar
3.安装完插件后再pages.json加上如下配置:
"easycom": {
"autoscan": true,
"custom": {
"lb-tabbar": "uni-lb-tabbar/components/lb-tabbar/lb-tabbar",
"lb-tabbar-item": "uni-lb-tabbar/components/lb-tabbar/lb-tabbar-item"
}
}
4.主页面demo6中如下代码
<template>
<view class="content">
<view class="layout-page">
<!-- 首页 -->
<home :visible="active === 'home'"
:height="height"
@change="handleTabChange">
</home>
<!-- 购物车 -->
<cart :visible="active === 'cart'"
:height="height"
@change="handleTabChange">
</cart>
<!-- 消息 -->
<notice :visible="active === 'notice'"
:height="height"
@change="handleTabChange">
</notice>
<!-- 我的 -->
<mine :visible="active === 'mine'"
:height="height"
@change="handleTabChange">
</mine>
</view>
<!-- 此处因为不需要点击凸起的发布按钮进行页面变化或跳转,故将v-model="active"修改成:value="active" -->
<!-- 在handleChange中手动判断进行active的赋值 -->
<lb-tabbar ref="tabbar"
:value="active"
:animate="animate"
@change="handleChange">
<lb-tabbar-item v-for="item in tabbars"
:key="item.name"
:name="item.name"
:icon="active === item.name ? item.iconActive : item.icon" //进行判断,是否点击状态
:dot="item.dot"
:info="item.info"
:raisede="item.raisede"
icon-prefix="iconfont"
@click="handleTabbarItemClick">
{{ item.text }}
</lb-tabbar-item>
</lb-tabbar>
</view>
</template>
<script>
import Home from '@/pages/demos/demo6/home/home'
import Cart from '@/pages/demos/demo6/cart/cart'
import Notice from '@/pages/demos/demo6/notice/notice'
import Mine from '@/pages/demos/demo6/mine/mine'
export default {
components: {
Home,
Cart,
Notice,
Mine
},
data () {
return {
active: '',
animate: 'zoomIn',
height: '',
tabbarHeight: '',
tabbars: [
{
name: 'home',
text: '首页',
icon: 'home',
dot: true
},
{
name: 'cart',
text: '购物车',
icon: 'cart'
},
{
name: 'plus',
text: '发布',
icon: 'plus',
raisede: true
},
{
name: 'notice',
text: '消息',
icon: 'notice',
info: 99
},
{
name: 'mine',
text: '我的',
icon: 'mine'
}
]
}
},
onLoad (query) {
// 可通过地址栏传tab参数可指定默认显示哪个tab页面
this.active = query.tab || 'home'
},
onReady () {
const res = uni.getSystemInfoSync()
const { windowHeight } = res
this.tabbarHeight = this.$refs.tabbar.tabbarHeight
this.height = windowHeight - this.tabbarHeight + 'px'
},
methods: {
handleChange (e) {
console.log('change::', e)
if (e.name !== 'plus') {
console.log("输出改变事件结果")
console.log(this.active)
this.active = e.name
}
},
handleTabChange (name) {
this.active = name
},
handleTabbarItemClick (e) {
console.log('click::', e)
if (e.name === 'plus') {
uni.showToast({
title: '发布',
icon: 'none'
})
}
}
},
watch: {
active: {
handler (newVal) {
if (newVal) {
// pages.json中设置页面的title为空,可在此处动态设置标题及颜色等等
const item = this.tabbars.find(item => item.name === this.active)
uni.setNavigationBarTitle({
title: item.text
})
}
},
immediate: true
}
}
}
</script>
<style lang="scss" scoped>
.content {
height: 100vh;
display: flex;
flex-direction: column;
box-sizing: border-box;
overflow: hidden;
.layout-page {
min-height: 0;
flex: 1;
/deep/ .page {
height: 100%;
}
}
}
</style>
可以看到在主页面里导入了四个页面组件,每个组件代表底部菜单的每一项
5.导航菜单组件home
<template>
<scroll-view class="page"
scroll-y
:style="{
display: visible ? 'block' : 'none'
}">
<view>首页</view>
<button @click="handleClick">切换到我的</button>
<view v-if="!isGetData">模拟数据加载中...</view>
<view v-for="item in list"
:key="item">
<text>首页页面的第{{item }}条数据</text>
</view>
</scroll-view>
</template>
<script>
export default {
props: {
visible: Boolean
},
data () {
return {
list: [],
isGetData: false
}
},
methods: {
// 模拟请求数据
getData () {
setTimeout(() => {
for (let i = 0; i < 50; i++) {
this.list.push(i + 1)
}
this.isGetData = true
}, 1000)
},
handleClick () {
this.$emit('change', 'mine')
}
},
watch: {
visible: {
handler (newVal) {
if (newVal && !this.isGetData) {
this.getData()
}
},
immediate: true
}
}
}
</script>
6.导航菜单组件home
<template>
<scroll-view class="page"
scroll-y
:style="{
display: visible ? 'block' : 'none'
}">
<view>首页</view>
<button @click="handleClick">切换到我的</button>
<view v-if="!isGetData">模拟数据加载中...</view>
<view v-for="item in list"
:key="item">
<text>首页页面的第{{item }}条数据</text>
</view>
</scroll-view>
</template>
<script>
export default {
props: {
visible: Boolean
},
data () {
return {
list: [],
isGetData: false
}
},
methods: {
// 模拟请求数据
getData () {
setTimeout(() => {
for (let i = 0; i < 50; i++) {
this.list.push(i + 1)
}
this.isGetData = true
}, 1000)
},
handleClick () {
this.$emit('change', 'mine')
}
},
watch: {
visible: {
handler (newVal) {
if (newVal && !this.isGetData) {
this.getData()
}
},
immediate: true
}
}
}
</script>
7.导航菜单组件cart
<template>
<scroll-view class="page"
scroll-y
:style="{
display: visible ? 'block' : 'none'
}">
<view>购物车</view>
<button @click="handleClick">切换到消息</button>
<view v-if="!isGetData">模拟数据加载中...</view>
<view v-for="item in list"
:key="item">
<text>购物车页面的第{{item }}条数据</text>
</view>
</scroll-view>
</template>
<script>
export default {
props: {
visible: Boolean
},
data () {
return {
list: [],
isGetData: false
}
},
onLoad() {
console.log(this.visible)
},
methods: {
// 模拟请求数据
getData () {
setTimeout(() => {
for (let i = 0; i < 50; i++) {
this.list.push(i + 1)
}
this.isGetData = true
}, 1000)
},
handleClick () {
this.$emit('change', 'notice')
}
},
watch: {
visible: {
handler (newVal) {
if (newVal && !this.isGetData) {
this.getData()
}
},
immediate: true
}
}
}
</script>
8.导航菜单组件mine
<template>
<scroll-view class="page"
scroll-y
:style="{
display: visible ? 'block' : 'none'
}">
<view>我的</view>
<button @click="handleClick">切换到购物车</button>
<view v-if="!isGetData">模拟数据加载中...</view>
<view v-for="item in list"
:key="item">
<text>我的页面的第{{item }}条数据</text>
</view>
</scroll-view>
</template>
<script>
export default {
props: {
visible: Boolean
},
data () {
return {
list: [],
isGetData: false
}
},
methods: {
// 模拟请求数据
getData () {
setTimeout(() => {
for (let i = 0; i < 50; i++) {
this.list.push(i + 1)
}
this.isGetData = true
}, 1000)
},
handleClick () {
this.$emit('change', 'cart')
}
},
watch: {
visible: {
handler (newVal) {
if (newVal && !this.isGetData) {
this.getData()
}
},
immediate: true
}
}
}
</script>
9.导航菜单组件notice
<template>
<scroll-view class="page"
scroll-y
:style="{
display: visible ? 'block' : 'none'
}">
<view>消息</view>
<button @click="handleClick">切换到首页</button>
<view v-if="!isGetData">模拟数据加载中...</view>
<view v-for="item in list"
:key="item">
<text>消息页面的第{{item }}条数据</text>
</view>
</scroll-view>
</template>
<script>
export default {
props: {
visible: Boolean
},
data () {
return {
list: [],
isGetData: false
}
},
methods: {
// 模拟请求数据
getData () {
setTimeout(() => {
for (let i = 0; i < 50; i++) {
this.list.push(i + 1)
}
this.isGetData = true
}, 1000)
},
handleClick () {
this.$emit('change', 'home')
}
},
watch: {
visible: {
handler (newVal) {
if (newVal && !this.isGetData) {
this.getData()
}
},
immediate: true
}
}
}
</script>
至此结束,运行时直接调用主页面就可以.
如有建议或者想法可以提出,共同改进共同学习
更多推荐
已为社区贡献4条内容
所有评论(0)