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