| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 | <template>	<view class="u-tabbar">		<view		    class="u-tabbar__content"		    ref="u-tabbar__content"		    @touchmove.stop.prevent="noop"		    :class="[border && 'u-border-top', fixed && 'u-tabbar--fixed']"		    :style="[tabbarStyle]"		>			<view class="u-tabbar__content__item-wrapper">				<slot />			</view>			<u-safe-bottom v-if="safeAreaInsetBottom"></u-safe-bottom>		</view>		<view		    class="u-tabbar__placeholder"			v-if="placeholder"		    :style="{				height: placeholderHeight + 'px',			}"		></view>	</view></template><script>	import props from './props.js';	// #ifdef APP-NVUE	const dom = uni.requireNativePlugin('dom')	// #endif	/**	 * Tabbar 底部导航栏	 * @description 此组件提供了自定义tabbar的能力。	 * @tutorial https://www.uviewui.com/components/tabbar.html	 * @property {String | Number}	value				当前匹配项的name	 * @property {Boolean}			safeAreaInsetBottom	是否为iPhoneX留出底部安全距离(默认 true )	 * @property {Boolean}			border				是否显示上方边框(默认 true )	 * @property {String | Number}	zIndex				元素层级z-index(默认 1 )	 * @property {String}			activeColor			选中标签的颜色(默认 '#1989fa' )	 * @property {String}			inactiveColor		未选中标签的颜色(默认 '#7d7e80' )	 * @property {Boolean}			fixed				是否固定在底部(默认 true )	 * @property {Boolean}			placeholder			fixed定位固定在底部时,是否生成一个等高元素防止塌陷(默认 true )	 * @property {Object}			customStyle			定义需要用到的外部样式	 * 	 * @example <u-tabbar :value="value2" :placeholder="false" @change="name => value2 = name" :fixed="false" :safeAreaInsetBottom="false"><u-tabbar-item text="首页" icon="home" dot ></u-tabbar-item></u-tabbar>	 */	export default {		name: 'u-tabbar',		mixins: [uni.$u.mpMixin, uni.$u.mixin,props],		data() {			return {				placeholderHeight: 0			}		},		computed: {			tabbarStyle() {				const style = {					zIndex: this.zIndex				}				// 合并来自父组件的customStyle样式				return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))			},			// 监听多个参数的变化,通过在computed执行对应的操作			updateChild() {				return [this.value, this.activeColor, this.inactiveColor]			},			updatePlaceholder() {				return [this.fixed, this.placeholder]			}		},		watch: {			updateChild() {				// 如果updateChildren中的元素发生了变化,则执行子元素初始化操作				this.updateChildren()			},			updatePlaceholder() {				// 如果fixed,placeholder等参数发生变化,重新计算占位元素的高度				this.setPlaceholderHeight()			}		},		created() {			this.children = []		},		mounted() {			this.setPlaceholderHeight()		},		methods: {			updateChildren() {				// 如果存在子元素,则执行子元素的updateFromParent进行更新数据				this.children.length && this.children.map(child => child.updateFromParent())			},			// 设置用于防止塌陷元素的高度			async setPlaceholderHeight() {				if (!this.fixed || !this.placeholder) return				// 延时一定时间				await uni.$u.sleep(20)				// #ifndef APP-NVUE				this.$uGetRect('.u-tabbar__content').then(({height = 50}) => {					// 修复IOS safearea bottom 未填充高度					this.placeholderHeight = height				})				// #endif				// #ifdef APP-NVUE				dom.getComponentRect(this.$refs['u-tabbar__content'], (res) => {					const {						size					} = res					this.placeholderHeight = size.height				})				// #endif			}		}	}</script><style lang="scss" scoped>	@import "../../libs/css/components.scss";	.u-tabbar {		@include flex(column);		flex: 1;		justify-content: center;				&__content {			@include flex(column);			background-color: #fff;						&__item-wrapper {				height: 50px;				@include flex(row);			}		}		&--fixed {			position: fixed;			bottom: 0;			left: 0;			right: 0;		}	}</style>
 |