123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- import {
- PropType,
- defineComponent,
- nextTick,
- onMounted,
- reactive,
- ref,
- watch
- } from 'vue';
- import styles from './index.module.less';
- import { useRect } from '@vant/use';
- import { useResizeObserver } from '@vueuse/core';
- export default defineComponent({
- name: 'm-sticky',
- props: {
- position: {
- type: String as PropType<'top' | 'bottom'>,
- default: 'top'
- },
- mode: {
- type: String as PropType<'fixed' | 'sticky'>,
- default: 'fixed'
- },
- offsetTop: {
- type: String,
- default: '0px'
- },
- offsetBottom: {
- default: '0px'
- },
- // 变量名
- varName: {
- type: String,
- default: '--header-height'
- }
- },
- emits: ['barHeight'],
- setup(props, { slots, emit }) {
- const forms = reactive({
- divStyle: {} as any,
- heightV: 0,
- sectionStyle: {
- width: '100%',
- height: 'auto',
- left: '0'
- }
- });
- const __initHeight = (height: any) => {
- forms.sectionStyle.height = `${height}px`;
- forms.heightV = height;
- // 设置名称
- document.documentElement.style.setProperty(props.varName, `${height}px`);
- emit('barHeight', height);
- };
- const divRef = ref();
- const div2Ref = ref();
- onMounted(() => {
- if (props.position === 'top') {
- forms.divStyle.top = props.offsetTop || '0px';
- } else {
- forms.divStyle.bottom = props.offsetBottom || '0px';
- }
- // const resize = new ResizeObserver(() => {
- // const { height } = useRect(div2Ref.value);
- // __initHeight(height);
- // });
- // resize.observe(divRef.value);
- try {
- useResizeObserver(div2Ref.value, (entries: any) => {
- const entry = entries[0];
- const { height } = entry.contentRect;
- if (Math.abs(height - forms.heightV) > 1) {
- setTimeout(() => {
- __initHeight(height);
- }, 10);
- }
- });
- } catch {}
- // nextTick(() => {
- // // 为了处理刚开始头部高度为0的情况
- // if (divRef.value) {
- // const { height } = useRect(divRef.value);
- // __initHeight(height);
- // setTimeout(() => {
- // const { height } = useRect(divRef.value);
- // // 判断获取的高度是否一致,如果一致则不做处理
- // if (height === forms.heightV) return;
- // __initHeight(height);
- // }, 200);
- // }
- // // 为了处理头部第一次获取高度不对的问题
- // if (div2Ref.value) {
- // setTimeout(() => {
- // const { height } = useRect(div2Ref.value);
- // if (height !== forms.heightV && props.position === 'top') {
- // __initHeight(height);
- // }
- // }, 1000);
- // }
- // });
- });
- watch(
- () => props.offsetTop,
- () => {
- forms.divStyle.top = props.offsetTop;
- }
- );
- watch(
- () => props.offsetBottom,
- () => {
- forms.divStyle.bottom = props.offsetBottom;
- }
- );
- return () => (
- <div
- style={[forms.sectionStyle]}
- class={props.mode === 'sticky' && styles.sticky}>
- <div
- ref={divRef}
- class={[
- 'van-sticky',
- props.mode === 'fixed' ? 'van-sticky--fixed' : ''
- ]}
- style={[forms.divStyle, forms.sectionStyle]}>
- <div ref={div2Ref}>{slots.default && slots.default()}</div>
- </div>
- </div>
- );
- }
- });
|