老师 hot.vue 中 my-tabs标签 属性 :defaultIndex 和 :config 的值 无法传递到 my-search.vue。对应的 watch方法 无法获取 值
<template>
<view class="hot-container">
<image class="logo" src="@/static/images/logo.png" mode="aspectFit"/>
<view class="search-box">
<my-search placeholderText="uni-app 自定义组件"></my-search>
</view>
<my-tabs :tabData="tabData" :defaultIndex="0" :config="{
textColor: '#00ff00'
}"></my-tabs>
</view>
</template>
<script>
import mySearch from '../../components/my-search/my-search.vue';
import { getHotTabs } from 'api/hot'
import MyTabs from '../../components/my-tabs/my-tabs.vue';
export default {
components: { mySearch, MyTabs },
data() {
return {
tabData: []
};
},
created() {
this.loadHotTabs();
},
methods: {
async loadHotTabs(){
const { data: res } = await getHotTabs();
this.tabData = res.list
}
}
}
</script>
<style lang="scss" scoped>
.hot-container {
background-color: $uni-bg-color;
.logo {
width: 100%;
height: 80px;
}
.search-box {
padding: 0 16px;
margin-bottom: $uni-spacing-col-base;
}
}
</style>
<template>
<view class="tab-container">
<view class="tab-box">
<scroll-view scroll-x class="scroll-view" scroll-with-animation :scroll-left="scrollLeft">
<view class="scroll-content">
<view class="tab-item-box">
<block v-for="(item,index) in tabData" :key="index">
<view
:id="'_tab_' + index"
class="tab-item"
:class="{ 'tab-item-active': activeIndex === index }"
@click="tabClick(index)"
:style="{
color:
activeIndex === index ? defaultConfig.activeTextColor : defaultConfig.textColor
}"
>{{item.label || item}}</view>
</block>
<view class="underLine" :style="{
transform: 'translateX(' + slider.left + 'px)',
width: defaultConfig.underLineWidth + 'px',
height: defaultConfig.underLineHeight + 'px',
backgroundColor: defaultConfig.underLineColor
}"></view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
name:"my-tabs",
props: {
tabData: {
type: Array,
default: () => { [] }
},
defaultIndex: {
type: Number,
default: 0
},
config: {
type: Object,
default: () => {
return {};
}
}
},
data() {
return {
tabList: [],
activeIndex: -1,
slider: {
left: 0
},
scrollLeft: 0,
defaultConfig: {
textColor: '#333333',
activeTextColor: '#f94d2a',
underLineWidth: 24,
underLineHeight: 2,
underLineColor: '#f94d2a'
}
};
},
watch: {
config: {
handler(val) {
this.defaultConfig = { ...this.defaultConfig, ...val };
console.log(this.defaultConfig)
},
immeditate: true
},
tabData: {
handler(val) {
this.tabList = val;
setTimeout(() => {
this.updateTabWidth();
},0)
},
immeditate: true
},
defaultIndex: {
handler(val) {
console.log(val)
this.activeIndex = val;
this.tabToIndex();
},
immeditate: true
}
},
methods: {
updateTabWidth() {
let data = this.tabList;
if(data.length === 0) return false;
const query = uni.createSelectorQuery().in(this);
//this.activeIndex = 0;
data.forEach((item, index) => {
query
.select('#_tab_' + index)
.boundingClientRect((res) => {
item._slider = {
left: res.left + (res.width - this.defaultConfig.underLineWidth)/2
};
if(data.length -1 === index) {
this.tabToIndex();
}
})
.exec();
})
},
tabClick(index) {
this.activeIndex = index;
this.tabToIndex();
this.$emit('tabClick',index);
},
tabToIndex() {
if (this.tabList.length === 0) return;
const index = this.activeIndex;
this.slider = {
left: this.tabList[index]._slider.left
};
this.scrollLeft = this.activeIndex * this.defaultConfig.underLineWidth;
}
}
}
</script>
<style lang="scss" scoped>
.tab-container {
font-size: $uni-font-size-base;
height: 45px;
line-height: 45px;
background-color: $uni-bg-color;
.tab-box {
width: 100%;
height: 45px;
display: flex;
position: relative;
.scroll-view {
white-space: nowrap;
width: 100%;
height: 100%;
box-sizing: border-box;
.scroll-content {
width: 100%;
height: 100%;
position: relative;
.tab-item-box {
height: 100%;
.tab-item {
height: 100%;
display: inline-block;
text-align: center;
padding: 0 15px;
position: relative;
text-align: center;
color: $uni-text-color;
&-active {
color: $uni-text-color-hot; // #f94d2a
font-weight: bold;
}
}
.underLine {
height: 2px;
width: 25px;
background-color: #f01414;
border-radius: 3px;
transition: 0.5s;
position: absolute;
bottom: 0;
}
}
}
}
}
}
</style>