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