|
@@ -1,5 +1,6 @@
|
|
|
import { pxCheck } from '@/packages/utils/pxCheck';
|
|
import { pxCheck } from '@/packages/utils/pxCheck';
|
|
|
import { TypeOfFun } from '@/packages/utils/util';
|
|
import { TypeOfFun } from '@/packages/utils/util';
|
|
|
|
|
+import { useRect } from '@/packages/utils/useRect';
|
|
|
import { onMounted, provide, VNode, ref, Ref, computed, onActivated, watch } from 'vue';
|
|
import { onMounted, provide, VNode, ref, Ref, computed, onActivated, watch } from 'vue';
|
|
|
export class Title {
|
|
export class Title {
|
|
|
title: string = '';
|
|
title: string = '';
|
|
@@ -54,6 +55,14 @@ export const component = {
|
|
|
titleGutter: {
|
|
titleGutter: {
|
|
|
type: [Number, String],
|
|
type: [Number, String],
|
|
|
default: 0
|
|
default: 0
|
|
|
|
|
+ },
|
|
|
|
|
+ sticky: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: false
|
|
|
|
|
+ },
|
|
|
|
|
+ top: {
|
|
|
|
|
+ type: Number,
|
|
|
|
|
+ default: 0
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
|
|
@@ -61,6 +70,8 @@ export const component = {
|
|
|
emits: ['update:modelValue', 'click', 'change'],
|
|
emits: ['update:modelValue', 'click', 'change'],
|
|
|
|
|
|
|
|
setup(props: any, { emit, slots }: any) {
|
|
setup(props: any, { emit, slots }: any) {
|
|
|
|
|
+ const container = ref(null);
|
|
|
|
|
+ let stickyFixed: boolean;
|
|
|
provide('activeKey', { activeKey: computed(() => props.modelValue) });
|
|
provide('activeKey', { activeKey: computed(() => props.modelValue) });
|
|
|
provide('autoHeight', { autoHeight: computed(() => props.autoHeight) });
|
|
provide('autoHeight', { autoHeight: computed(() => props.autoHeight) });
|
|
|
const titles: Ref<Title[]> = ref([]);
|
|
const titles: Ref<Title[]> = ref([]);
|
|
@@ -112,17 +123,31 @@ export const component = {
|
|
|
}
|
|
}
|
|
|
findTabsIndex(props.modelValue);
|
|
findTabsIndex(props.modelValue);
|
|
|
};
|
|
};
|
|
|
|
|
+ const onStickyScroll = (params: { top: number; fixed: boolean }) => {
|
|
|
|
|
+ stickyFixed = params.fixed;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
watch(
|
|
watch(
|
|
|
() => slots.default?.(),
|
|
() => slots.default?.(),
|
|
|
(vnodes: VNode[]) => {
|
|
(vnodes: VNode[]) => {
|
|
|
init(vnodes);
|
|
init(vnodes);
|
|
|
}
|
|
}
|
|
|
);
|
|
);
|
|
|
-
|
|
|
|
|
|
|
+ const getScrollTopRoot = () => {
|
|
|
|
|
+ return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
|
|
|
|
|
+ };
|
|
|
watch(
|
|
watch(
|
|
|
() => props.modelValue,
|
|
() => props.modelValue,
|
|
|
(value: string | number) => {
|
|
(value: string | number) => {
|
|
|
findTabsIndex(value);
|
|
findTabsIndex(value);
|
|
|
|
|
+ if (stickyFixed) {
|
|
|
|
|
+ let top = useRect(container.value!).top + getScrollTopRoot();
|
|
|
|
|
+ let value = Math.ceil(top - props.top);
|
|
|
|
|
+ window.scrollTo({
|
|
|
|
|
+ top: value,
|
|
|
|
|
+ behavior: 'smooth'
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
);
|
|
);
|
|
|
onMounted(init);
|
|
onMounted(init);
|
|
@@ -164,13 +189,14 @@ export const component = {
|
|
|
emit('change', item);
|
|
emit('change', item);
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
return {
|
|
return {
|
|
|
titles,
|
|
titles,
|
|
|
contentStyle,
|
|
contentStyle,
|
|
|
tabsNavStyle,
|
|
tabsNavStyle,
|
|
|
titleStyle,
|
|
titleStyle,
|
|
|
tabsActiveStyle,
|
|
tabsActiveStyle,
|
|
|
|
|
+ container,
|
|
|
|
|
+ onStickyScroll,
|
|
|
...methods
|
|
...methods
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|