请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

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

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

图片描述

正在回答 回答被采纳积分+3

1回答

Sunday 2022-11-28 19:50:44

你好

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

0 回复 有任何疑惑可以回复我~
  • 提问者 qq_慕前端859935 #1
    老师现在,我的问题是现在是hot.vue 中的 :defaultIndex="0" ,但这个0没传递到 my-tabs.vue 中 ,还是默认-1,导致初始化后热榜那的下划线的位置不对。
    hot.vue 中的:config="{textColor: '#00ff00'}" ,也没传递到my-tabs.vue 中,对应的样式还是默认样式。
    回复 有任何疑惑可以回复我~ 2022-11-28 20:04:03
  • Sunday 回复 提问者 qq_慕前端859935 #2
    从你代码中来看你的 defaultIndex 默认值也是 0 , 并非 -1 
    defaultIndex: {
    				type: Number,
    				default: 0
    			},
    并且查看你的代码, defaultIndex 的 props 这个写法并没有问题呢。
    回复 有任何疑惑可以回复我~ 2022-11-28 20:07:38
  • 提问者 qq_慕前端859935 回复 Sunday #3
    说错了应该 activeIndex: -1 ,正常应该是在hot.vue的 :defaultIndex="0" 将0 传递给my-tabs.vue的 watch中的 defaultIndex 监控变化 后将 0 赋值给 activeIndex ,这时 activeIndex 就是0了,activeIndex是0的话,滑块的位置就对了,是-1的话就不对。 我感觉是没从hot.vue 传递到my-tabs.vue中,但对好几遍代码,没看到哪和老师写的不一样。
    回复 有任何疑惑可以回复我~ 2022-11-28 20:19:10
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信