绩效考核手机版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.2 KiB

3 years ago
<template>
<view :style="wrap_style">
<view :id="$sUid" class="s-fixed" :class="custom_class" :style="c_style">
<s-safe-area-inset
v-if="fixed && safeAreaInset && position === 'top'"
position="top"
/>
<slot />
<s-safe-area-inset
v-if="fixed && safeAreaInset && position === 'bottom'"
position="bottom"
/>
</view>
</view>
</template>
<script>
import componentMixin from '../../mixins/componentMixin';
/**
* s-fixed 固定定位
* @description 固定某个元素到一个位置
* @property {String} position = [top|bottom] 固定方向
* @property {Number|String} top 顶部的距离单位rpx
* @property {Number|String} bottom 底部的距离单位rpx
* @property {Boolean} fixed 启用固定功能
* @property {Number|String} zIndex z-index
* @property {String} background 背景色
* @property {Boolean} safeAreaInset 是否空出底部或顶部安全距离
* @example <s-fixed></s-fixed>
*/
export default {
name: 'SFixed',
mixins: [componentMixin],
props: {
position: {
type: String,
default: 'bottom',
},
top: {
type: [Number, String],
default: 0,
},
bottom: {
type: [Number, String],
default: 0,
},
fixed: {
type: Boolean,
default: true,
},
zIndex: [Number, String],
background: String,
safeAreaInset: Boolean,
},
data: () => ({
isFixed: false,
width: 0,
height: 0,
windowTop: 0,
windowBottom: 0,
}),
computed: {
wrap_style() {
return this.$mergeStyle({
height: this.isFixed ? this.height + 'px' : '',
});
},
c_style() {
const style = {
background: this.background,
};
if (this.fixed && !this.isFixed) {
style.visibility = 'hidden';
}
if (this.isFixed) {
style.position = 'fixed';
style.width = this.width + 'px';
style[this.position] = (this.offset + this.otherHeight) + 'px';
style.zIndex = this.zIndex;
}
return this.$mergeStyle(style, this.custom_style);
},
offset() {
return this.$toPx(this.position === 'top' ? this.top : this.bottom);
},
otherHeight() {
return parseInt(this.position === 'top' ? this.windowTop : this.windowBottom);
},
refreshState() {
return [
this.fixed,
this.position,
this.top,
this.bottom,
this.safeAreaInset,
];
},
},
watch: {
refreshState() {
this.refresh();
},
},
created() {
const systemInfo = uni.getSystemInfoSync();
this.windowTop = systemInfo.windowTop || 0;
this.windowBottom = systemInfo.windowBottom || 0;
},
mounted() {
this.$nextTick(this.refresh);
},
methods: {
refresh() {
if (!this._isMounted || this._isDestroyed) return;
if (!this.fixed) {
this.isFixed = false;
} else {
this.$nextTick(() => {
this.$getRect(`#${this.$sUid}`).then(rect => {
this.isFixed = true;
this.width = rect.width;
this.height = rect.height;
});
});
}
},
},
};
</script>
<style lang="scss" src="./index.scss"></style>