I want to implement a component of tabbar
myself, so I define two components to combine the implementation:
<template>
<div class="tabbar">
<tab-item v-for="item in tabItems"
:key="item.index"
v-bind="item"
@tabItemOnClick="tabItemOnClick"
>
</tab-item>
</div>
</template>
<script>
import TabItem from "./tabitem.vue"
export default {
name: "tab-bar",
components: {TabItem},
props: {
tabItems: {
default: []
}
},
data () {
return {
selectedIndex: 0
}
},
created () {
this.select(this.selectedIndex)
},
methods: {
tabItemOnClick (params) {
this.selectedIndex = params.index
this.select(this.selectedIndex)
this.toast(this.selectedIndex)
},
select (index) {
for (let i = 0; i < this.tabItems.length; iPP) {
var tabItem = this.tabItems[i]
if (i === index) {
tabItem.selected = true
} else {
tabItem.selected = false
}
}
}
}
}
</script>
<style>
.tabbar {
background-color: -sharpffffff;
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100px;
flex-wrap: nowrap;
flex-direction: row;
}
</style>
< H1 > 2.TabBarItem < / H1 >
<template>
<div class="bar-item" @click="onTabItemClick">
<text class="icon iconfont" :class="[ selected ? "active" : "" ]">{{ icon }}</text>
<text class="text" :class="[ selected ? "active" : "" ]">{{ title }}</text>
<div v-if="parseInt(dot) === 0">
<text :class="[ needNum ? "notice" : "dot" ]">{{ dot }}</text>
</div>
</div>
</template>
<script>
export default {
name: "tab-item",
props: {
index: {
type: Number,
required: true
},
icon: {
type: String,
default: ""
},
title: {
type: String,
default: ""
},
dot: {
type: String,
default: "0"
},
needNum: {
type: Boolean,
default: true
},
selected: {
type: Boolean,
default: false
}
},
data () {
return {
}
},
methods: {
setNum (num) {
if (num <= 0) {
this.dot = ""
} else {
this.dot = num + ""
}
},
onTabItemClick () {
var params = {
index: this.index
}
this.$emit("tabItemOnClick", params)
}
},
watch: {
selected: function (val) {
this.toast("selected: " + this.selected + ", " + val)
}
}
}
</script>
<style>
.bar-item {
background-color: -sharpafddff;
flex: 1;
}
.text, .icon {
color: -sharp666666;
text-align: center;
}
.iconfont {
font-family: iconfont;
}
.icon {
padding-top: 14px;
font-size: 38px;
}
.text {
font-size: 22px;
padding-top: 2px;
}
.active {
color: -sharpb4282d
}
.notice {
position: absolute;
top: 10px;
right: 30px;
width: 30px;
height: 30px;
border-radius: 100%;
font-size: 26px;
line-height: 30px;;
text-align: center;
color: -sharpffffff;
background-color: -sharpff0000;
}
.dot {
position: absolute;
top:15px;
right: 40px;
height: 15px;
width: 15px;
border-radius: 100%;
background-color: -sharpff0000;
}
</style>
< H1 > 3. Use < / H1 >
<tab-bar :tabItems="tabs"></tab-bar>
tabs calculates attribute assignments through computed:
computed: {
tabs: function () {
return [{
index: 0,
icon: "",
title: "",
dot: "0",
needNum: true,
selected: true
},
{
index: 1,
icon: "",
title: "",
dot: "1",
needNum: true,
selected: false
},
{
index: 2,
icon: "",
title: "",
dot: "5",
needNum: true,
selected: false
},
{
index: 3,
icon: "",
title: "",
dot: "1",
needNum: false,
selected: false
}]
}
}
when the TabBarItem is clicked, the click event can be passed to the parent component and modify the selected
property of the selected tabItem, but the style
of the modified tabBarItem component is not changed, and the watch
is not changed in the child component. I don"t understand why?