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?
