"use strict"; const common_vendor = require("../../common/vendor.js"); const _sfc_main = { name: "SmartTabs", props: { // 是否支持滚动 scrollEnable: { type: Boolean, required: false, default: false }, // 选项卡配置 tabs: { type: Array, required: true, default: () => [] }, // 初始选中的索引 initialIndex: { type: Number, default: 0 }, // 动画时长 duration: { type: Number, default: 300 }, // 是否显示徽章 showBadge: { type: Boolean, default: true }, // 激活状态颜色 activeColor: { type: String, default: "#007AFF" }, // 非激活状态颜色 inactiveColor: { type: String, default: "#333" }, // 最小项宽度(用于平铺模式) minItemWidth: { type: Number, default: 120 // rpx } }, data() { return { currentIndex: this.initialIndex, scrollLeft: 0, tabWidths: [], containerWidth: 0, activeTabId: `tab_${this.initialIndex}`, canScrollLeft: false, canScrollRight: false }; }, mounted() { this.$nextTick(() => { this.calculateLayout(); }); }, methods: { // 计算布局 calculateLayout() { this.getContainerWidth().then(() => { this.calculateTabPositions().then(() => { this.checkScrollability(); this.scrollToCurrentTab(); }); }); }, // 获取容器宽度 getContainerWidth() { return new Promise((resolve) => { const query = common_vendor.index.createSelectorQuery().in(this); query.select(".tabs-header").boundingClientRect(); query.exec((res) => { if (res && res[0]) { this.containerWidth = res[0].width; } resolve(); }); }); }, // 计算选项卡位置 calculateTabPositions() { return new Promise((resolve) => { const query = common_vendor.index.createSelectorQuery().in(this); this.tabs.forEach((_, index) => { query.select(`#tab_${index}`).boundingClientRect(); }); query.exec((res) => { this.tabWidths = res.map((item) => item ? item.width : 0); resolve(); }); }); }, // 检查是否需要滚动 checkScrollability() { this.checkScrollState(); }, // 检查滚动状态 checkScrollState() { if (!this.$props.scrollEnable) { this.canScrollLeft = false; this.canScrollRight = false; return; } this.canScrollLeft = this.scrollLeft > 0; const totalWidth = this.tabWidths.reduce((sum, width) => sum + width, 0); this.canScrollRight = this.scrollLeft < totalWidth - this.containerWidth; }, // 滚动到当前选项卡 scrollToCurrentTab() { if (this.tabWidths.length === 0 || !this.$props.scrollEnable) return; let totalWidth = 0; for (let i = 0; i < this.currentIndex; i++) { totalWidth += this.tabWidths[i]; } const currentTabWidth = this.tabWidths[this.currentIndex]; const scrollLeft = totalWidth - (this.containerWidth - currentTabWidth) / 2; this.scrollLeft = scrollLeft; this.activeTabId = `tab_${this.currentIndex}`; this.checkScrollState(); }, // 处理滚动事件 handleScroll(e) { this.scrollLeft = e.detail.scrollLeft; this.checkScrollState(); }, // 处理选项卡点击 handleTabClick(index) { if (this.currentIndex !== index) { this.currentIndex = index; this.scrollToCurrentTab(); this.$emit("change", index); } }, // 处理滑动切换 handleSwiperChange(e) { const index = e.detail.current; if (this.currentIndex !== index) { this.currentIndex = index; this.scrollToCurrentTab(); this.$emit("change", index); } }, // 获取选项卡样式 getTabStyle(index) { const isActive = this.currentIndex === index; const style = { color: isActive ? this.activeColor : this.inactiveColor, fontWeight: isActive ? "bold" : "normal", width: this.scrollEnable ? "auto" : `${100 / this.tabs.length}%` }; if (!this.$props.scrollEnable) { style.flex = "1"; style.minWidth = "0"; style.textAlign = "center"; } return style; }, getScrollViewStyle() { console.log("aaa", this.$props.scrollEnable); const isActive = this.$props.scrollEnable; const style = { "--scroll-content-display": isActive ? "block" : "flex" }; console.log("aaa", this.$props.scrollEnable); return style; }, // 切换到指定选项卡 switchTo(index) { if (index >= 0 && index < this.tabs.length && index !== this.currentIndex) { this.currentIndex = index; this.scrollToCurrentTab(); this.$emit("change", index); } }, // 向左滚动 scrollLeftByStep() { this.scrollLeft = Math.max(0, this.scrollLeft - 100); this.checkScrollState(); }, // 向右滚动 scrollRightByStep() { const totalWidth = this.tabWidths.reduce((sum, width) => sum + width, 0); const maxScroll = totalWidth - this.containerWidth; this.scrollLeft = Math.min(maxScroll, this.scrollLeft + 100); this.checkScrollState(); } }, watch: { initialIndex(newVal) { if (newVal !== this.currentIndex) { this.currentIndex = newVal; this.scrollToCurrentTab(); } }, tabs() { this.$nextTick(() => { this.calculateLayout(); }); } } }; const __injectCSSVars__ = () => { common_vendor.useCssVars((_ctx) => ({ "71c614aa": _ctx.activeColor })); }; const __setup__ = _sfc_main.setup; _sfc_main.setup = __setup__ ? (props, ctx) => { __injectCSSVars__(); return __setup__(props, ctx); } : __injectCSSVars__; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { return { a: common_vendor.f($props.tabs, (tab, index, i0) => { return common_vendor.e({ a: common_vendor.t(tab.label), b: $props.showBadge && tab.badge }, $props.showBadge && tab.badge ? { c: common_vendor.t(tab.badge > 99 ? "99+" : tab.badge) } : {}, { d: index, e: `tab_${index}`, f: $data.currentIndex === index ? 1 : "", g: common_vendor.s($options.getTabStyle(index)), h: common_vendor.o(($event) => $options.handleTabClick(index), index) }); }), b: $props.scrollEnable, c: $data.scrollLeft, d: $props.scrollEnable, e: $data.activeTabId, f: common_vendor.s($options.getScrollViewStyle()), g: common_vendor.o((...args) => $options.handleScroll && $options.handleScroll(...args)), h: common_vendor.s(_ctx.__cssVars()) }; } const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-f67213a1"]]); wx.createComponent(Component);