hot.vue 中 my-tabs标签 属性 :defaultIndex 和 :config 的值 无法传递到 my-search.vue

来源:5-21 tabs组件 - 增加可配置项

qq_慕前端859935

2022-11-28

老师 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>

图片描述

写回答

1回答

Sunday

2022-11-28

你好

根据这个错误是因为你从 undefined 中读取了一个 _slider 的属性,在 my-tabs 中。 和你的 props 应该并没有关系才对

0
5
Sunday
回复
qq_慕前端859935
好的。
2022-11-28
共5条回复

uni-app从入门到进阶 系统完成项目实战

专门为小程序0基础学员而设,让你拥有能上线的作品

1105 学习 · 743 问题

查看课程