import { ref, PropType, defineComponent } from 'vue'; // Utils import { createNamespace, getZIndexStyle } from '../utils'; import { BORDER_TOP_BOTTOM } from '../utils/constant'; import { callInterceptor, Interceptor } from '../utils/interceptor'; // Composables import { useChildren } from '@vant/use'; import { usePlaceholder } from '../composables/use-placeholder'; const [name, bem] = createNamespace('tabbar'); export const TABBAR_KEY = Symbol(name); export type TabbarProvide = { props: { route?: boolean; modelValue: number | string; activeColor?: string; inactiveColor?: string; }; setActive: (active: number | string) => void; }; export default defineComponent({ name, props: { route: Boolean, zIndex: [Number, String], placeholder: Boolean, activeColor: String, beforeChange: Function as PropType, inactiveColor: String, modelValue: { type: [Number, String], default: 0, }, border: { type: Boolean, default: true, }, fixed: { type: Boolean, default: true, }, safeAreaInsetBottom: { type: Boolean as PropType, default: null, }, }, emits: ['change', 'update:modelValue'], setup(props, { emit, slots }) { const root = ref(); const { linkChildren } = useChildren(TABBAR_KEY); const renderPlaceholder = usePlaceholder(root, bem); const isUnfit = () => { if (props.safeAreaInsetBottom !== null) { return !props.safeAreaInsetBottom; } // enable safe-area-inset-bottom by default when fixed return !props.fixed; }; const renderTabbar = () => { const { fixed, zIndex, border } = props; return (
{slots.default?.()}
); }; const setActive = (active: number | string) => { if (active !== props.modelValue) { callInterceptor({ interceptor: props.beforeChange, args: [active], done() { emit('update:modelValue', active); emit('change', active); }, }); } }; linkChildren({ props, setActive }); return () => { if (props.fixed && props.placeholder) { return renderPlaceholder(renderTabbar); } return renderTabbar(); }; }, });