fix: tabs hotreload error

refactor-tabs
tangjinzhou 2021-10-06 13:07:19 +08:00
parent cd9f592c2e
commit 8937d92cdc
5 changed files with 18 additions and 24 deletions

View File

@ -1,11 +1,12 @@
import type { Ref } from 'vue'; import type { Ref, ComponentPublicInstance } from 'vue';
import { onBeforeUpdate, ref } from 'vue'; import { onBeforeUpdate, ref } from 'vue';
export type UseRef = [(el: any, key: string | number) => void, Ref<any>]; type RefType = HTMLElement | ComponentPublicInstance;
export type Refs = Record<string | number, any>; export type Refs = Record<string | number, RefType>;
export type UseRef = [(el: RefType, key: string | number) => void, Ref<Refs>];
export const useRef = (): UseRef => { export const useRef = (): UseRef => {
const refs = ref<Refs>({}); const refs = ref<Refs>({});
const setRef = (el: any, key: string | number) => { const setRef = (el: RefType, key: string | number) => {
refs.value[key] = el; refs.value[key] = el;
}; };
onBeforeUpdate(() => { onBeforeUpdate(() => {

View File

@ -1,6 +1,6 @@
import type { Tab, EditableConfig } from '../interface'; import type { Tab, EditableConfig } from '../interface';
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import { onBeforeUnmount, defineComponent, computed, ref } from 'vue'; import { defineComponent, computed, ref } from 'vue';
import type { FocusEventHandler } from '../../../_util/EventInterface'; import type { FocusEventHandler } from '../../../_util/EventInterface';
import KeyCode from '../../../_util/KeyCode'; import KeyCode from '../../../_util/KeyCode';
import classNames from '../../../_util/classNames'; import classNames from '../../../_util/classNames';
@ -37,7 +37,7 @@ export default defineComponent({
}, },
renderWrapper: { type: Function as PropType<(node: any) => any> }, renderWrapper: { type: Function as PropType<(node: any) => any> },
removeAriaLabel: { type: String }, removeAriaLabel: { type: String },
onRemove: { type: Function as PropType<() => void> }, // onRemove: { type: Function as PropType<() => void> },
onFocus: { type: Function as PropType<FocusEventHandler> }, onFocus: { type: Function as PropType<FocusEventHandler> },
}, },
emits: ['click', 'resize', 'remove', 'focus'], emits: ['click', 'resize', 'remove', 'focus'],
@ -52,9 +52,9 @@ export default defineComponent({
expose({ expose({
domRef, domRef,
}); });
onBeforeUnmount(() => { // onBeforeUnmount(() => {
props.onRemove(); // props.onRemove();
}); // });
function onRemoveTab(event: MouseEvent | KeyboardEvent) { function onRemoveTab(event: MouseEvent | KeyboardEvent) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();

View File

@ -15,7 +15,6 @@ import useOffsets from '../hooks/useOffsets';
import OperationNode from './OperationNode'; import OperationNode from './OperationNode';
import { useInjectTabs } from '../TabContext'; import { useInjectTabs } from '../TabContext';
import useTouchMove from '../hooks/useTouchMove'; import useTouchMove from '../hooks/useTouchMove';
import useRefs from '../hooks/useRefs';
import AddButton from './AddButton'; import AddButton from './AddButton';
import type { Key } from '../../../_util/type'; import type { Key } from '../../../_util/type';
import type { ExtractPropTypes, PropType, CSSProperties } from 'vue'; import type { ExtractPropTypes, PropType, CSSProperties } from 'vue';
@ -27,6 +26,7 @@ import wrapperRaf from '../../../_util/raf';
import classNames from '../../../_util/classNames'; import classNames from '../../../_util/classNames';
import ResizeObserver from '../../../vc-resize-observer'; import ResizeObserver from '../../../vc-resize-observer';
import { toPx } from '../../../_util/util'; import { toPx } from '../../../_util/util';
import useRef from '../../../_util/hooks/useRef';
const DEFAULT_SIZE = { width: 0, height: 0, left: 0, top: 0, right: 0 }; const DEFAULT_SIZE = { width: 0, height: 0, left: 0, top: 0, right: 0 };
const tabNavListProps = () => { const tabNavListProps = () => {
return { return {
@ -34,7 +34,6 @@ const tabNavListProps = () => {
tabPosition: { type: String as PropType<TabPosition> }, tabPosition: { type: String as PropType<TabPosition> },
activeKey: { type: [String, Number] }, activeKey: { type: [String, Number] },
rtl: { type: Boolean }, rtl: { type: Boolean },
panes: PropTypes.any,
animated: { type: Object as PropType<AnimatedConfig>, default: undefined as AnimatedConfig }, animated: { type: Object as PropType<AnimatedConfig>, default: undefined as AnimatedConfig },
extra: PropTypes.any, extra: PropTypes.any,
editable: { type: Object as PropType<EditableConfig> }, editable: { type: Object as PropType<EditableConfig> },
@ -63,7 +62,7 @@ export default defineComponent({
name: 'TabNavList', name: 'TabNavList',
inheritAttrs: false, inheritAttrs: false,
props: tabNavListProps(), props: tabNavListProps(),
slots: ['panes', 'moreIcon', 'extra'], slots: ['moreIcon', 'extra'],
emits: ['tabClick', 'tabScroll'], emits: ['tabClick', 'tabScroll'],
setup(props, { attrs, slots }) { setup(props, { attrs, slots }) {
const { tabs, prefixCls } = useInjectTabs(); const { tabs, prefixCls } = useInjectTabs();
@ -71,8 +70,7 @@ export default defineComponent({
const tabListRef = ref<HTMLDivElement>(); const tabListRef = ref<HTMLDivElement>();
const operationsRef = ref<{ $el: HTMLDivElement }>(); const operationsRef = ref<{ $el: HTMLDivElement }>();
const innerAddButtonRef = ref<HTMLButtonElement>(); const innerAddButtonRef = ref<HTMLButtonElement>();
const [getBtnRef, removeBtnRef] = useRefs(); const [setRef, btnRefs] = useRef();
const tabPositionTopOrBottom = computed( const tabPositionTopOrBottom = computed(
() => props.tabPosition === 'top' || props.tabPosition === 'bottom', () => props.tabPosition === 'top' || props.tabPosition === 'bottom',
); );
@ -315,8 +313,8 @@ export default defineComponent({
setTabSizes(() => { setTabSizes(() => {
const newSizes: TabSizeMap = new Map(); const newSizes: TabSizeMap = new Map();
tabs.value.forEach(({ key }) => { tabs.value.forEach(({ key }) => {
const btnRef = getBtnRef(key).value; const btnRef = btnRefs.value[key];
const btnNode = (btnRef as any).$el || btnRef; const btnNode = (btnRef as any)?.$el || btnRef;
if (btnNode) { if (btnNode) {
newSizes.set(key, { newSizes.set(key, {
width: btnNode.offsetWidth, width: btnNode.offsetWidth,
@ -459,13 +457,10 @@ export default defineComponent({
editable={editable} editable={editable}
active={key === activeKey} active={key === activeKey}
removeAriaLabel={locale?.removeAriaLabel} removeAriaLabel={locale?.removeAriaLabel}
ref={getBtnRef(key)} ref={r => setRef(r, key)}
onClick={e => { onClick={e => {
onTabClick(key, e); onTabClick(key, e);
}} }}
onRemove={() => {
removeBtnRef(key);
}}
onFocus={() => { onFocus={() => {
scrollToTab(key); scrollToTab(key);
doLockAnimation(); doLockAnimation();
@ -537,7 +532,6 @@ export default defineComponent({
</ResizeObserver> </ResizeObserver>
</div> </div>
</ResizeObserver> </ResizeObserver>
<OperationNode <OperationNode
{...props} {...props}
ref={operationsRef} ref={operationsRef}

View File

@ -256,7 +256,6 @@ const InternalTabs = defineComponent({
onTabClick: onInternalTabClick, onTabClick: onInternalTabClick,
onTabScroll, onTabScroll,
style: tabBarStyle, style: tabBarStyle,
panes: flattenChildren(slots.default?.()),
}; };
if (renderTabBar) { if (renderTabBar) {

View File

@ -130,8 +130,8 @@ export default function useTouchMove(
document.addEventListener('touchend', onProxyTouchEnd, { passive: false }); document.addEventListener('touchend', onProxyTouchEnd, { passive: false });
// No need to clean up since element removed // No need to clean up since element removed
domRef.value.addEventListener('touchstart', onProxyTouchStart, { passive: false }); domRef.value?.addEventListener('touchstart', onProxyTouchStart, { passive: false });
domRef.value.addEventListener( domRef.value?.addEventListener(
'wheel', 'wheel',
onProxyWheel, onProxyWheel,
supportsPassive ? { passive: true } : false, supportsPassive ? { passive: true } : false,