-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
137 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,20 @@ | ||
import type { App } from 'vue'; | ||
import Tabs from './src/tabs'; | ||
import Tab from './src/components/tab/tab'; | ||
import type { App } from 'vue' | ||
import Tab from './src/components/tab/tab' | ||
import Tabs from './src/tabs' | ||
|
||
Tabs.install = function (app: App): void { | ||
app.component(Tabs.name, Tabs); | ||
app.component(Tab.name, Tab); | ||
}; | ||
app.component(Tabs.name, Tabs) | ||
app.component(Tab.name, Tab) | ||
} | ||
|
||
export { Tabs, Tab }; | ||
export { Tab, Tabs } | ||
|
||
export default { | ||
title: 'Tabs 选项卡', | ||
category: '导航', | ||
status: undefined, // TODO: 组件若开发完成则填入"100%",并删除该注释 | ||
install(app: App): void { | ||
app.component(Tabs.name, Tabs); | ||
app.component(Tab.name, Tab); | ||
} | ||
}; | ||
app.component(Tabs.name, Tabs) | ||
app.component(Tab.name, Tab) | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,21 @@ | ||
import { ExtractPropTypes, PropType } from 'vue'; | ||
import type { ExtractPropTypes, PropType } from 'vue' | ||
|
||
export type LabelType = string | number; | ||
export type NameType = string | number; | ||
export type LabelType = string | number | ||
export type NameType = string | number | ||
|
||
export const tabProps = { | ||
label: { | ||
type: [String, Number] as PropType<LabelType>, | ||
default: null | ||
default: null, | ||
}, | ||
name: { | ||
type: [String, Number] as PropType<NameType>, | ||
default: null | ||
default: null, | ||
}, | ||
disabled: { | ||
type: Boolean, | ||
default: false | ||
} | ||
} as const; | ||
default: false, | ||
}, | ||
} as const | ||
|
||
export type TabProps = ExtractPropTypes<typeof tabProps>; | ||
export type TabProps = ExtractPropTypes<typeof tabProps> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,37 @@ | ||
import { defineComponent, inject, onUnmounted } from 'vue'; | ||
import { tabsInjectionKey, TabsState } from '../../tabs-types'; | ||
import { tabProps, TabProps } from './tab-types'; | ||
import './tab.scss'; | ||
import { useNamespace } from '../../../../shared/hooks/use-namespace'; | ||
import { defineComponent, inject, onUnmounted } from 'vue' | ||
import type { TabsState } from '../../tabs-types' | ||
import { useNamespace } from '../../../../shared/hooks/use-namespace' | ||
import { tabsInjectionKey } from '../../tabs-types' | ||
import type { TabProps } from './tab-types' | ||
import { tabProps } from './tab-types' | ||
import './tab.scss' | ||
|
||
export default defineComponent({ | ||
name: 'CTab', | ||
props: tabProps, | ||
emits: [], | ||
setup(props: TabProps, { slots }) { | ||
const ns = useNamespace('tab'); | ||
const ns = useNamespace('tab') | ||
|
||
const tabsState = inject<TabsState>(tabsInjectionKey); | ||
tabsState?.data?.push(props); | ||
tabsState?.slots?.push(slots); | ||
const tabsState = inject<TabsState>(tabsInjectionKey) | ||
tabsState?.data?.push(props) | ||
tabsState?.slots?.push(slots) | ||
|
||
// 组件卸载移除 组件props数据缓存 | ||
onUnmounted(() => { | ||
if (tabsState) { | ||
tabsState.data = tabsState.data?.filter( | ||
(item) => item.name !== props.name | ||
); | ||
item => item.name !== props.name, | ||
) | ||
} | ||
}); | ||
}) | ||
|
||
return () => { | ||
return props.name === tabsState?.active ? ( | ||
<div class={ns.b()}>{slots.default && slots.default()}</div> | ||
) : null; | ||
}; | ||
} | ||
}); | ||
return props.name === tabsState?.active | ||
? ( | ||
<div class={ns.b()}>{slots.default && slots.default()}</div> | ||
) | ||
: null | ||
} | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,74 @@ | ||
import { defineComponent, inject, computed } from 'vue'; | ||
import type { | ||
TabsProps, | ||
TabsState, | ||
} from '../../tabs-types' | ||
import type { TabProps } from '../tab/tab-types' | ||
import { computed, defineComponent, inject } from 'vue' | ||
import { useNamespace } from '../../../../shared/hooks/use-namespace' | ||
import { | ||
tabsInjectionKey, | ||
tabsProps, | ||
TabsProps, | ||
TabsState | ||
} from '../../tabs-types'; | ||
import { TabProps } from '../tab/tab-types'; | ||
import './tabs-nav.scss'; | ||
import { useNamespace } from '../../../../shared/hooks/use-namespace'; | ||
} from '../../tabs-types' | ||
import './tabs-nav.scss' | ||
|
||
export default defineComponent({ | ||
name: 'CTabs-nav', | ||
props: tabsProps, | ||
emits: ['active-tab-change'], | ||
setup(props: TabsProps, { emit }) { | ||
const ns = useNamespace('tabs-nav'); | ||
const ns = useNamespace('tabs-nav') | ||
|
||
const tabsState = inject<TabsState>(tabsInjectionKey); | ||
const tabsState = inject<TabsState>(tabsInjectionKey) | ||
|
||
const navList = computed(() => tabsState?.data || []); | ||
const slotsList = computed(() => tabsState?.slots || []); | ||
const navList = computed(() => tabsState?.data || []) | ||
const slotsList = computed(() => tabsState?.slots || []) | ||
|
||
const containerClass = computed(() => { | ||
let cls = ns.b(); | ||
let cls = ns.b() | ||
if (props.type) { | ||
cls += `-${props.type}`; | ||
cls += `-${props.type}` | ||
} | ||
return `${cls}--${props.tabPosition}`; | ||
}); | ||
return `${cls}--${props.tabPosition}` | ||
}) | ||
|
||
const getNavItemClass = (item: TabProps) => { | ||
const itemClass = `${containerClass.value}-item`; | ||
const itemActiveClass = | ||
tabsState?.active === item.name ? `${itemClass}-active` : ''; | ||
const itemClass = `${containerClass.value}-item` | ||
const itemActiveClass | ||
= tabsState?.active === item.name ? `${itemClass}-active` : '' | ||
|
||
return `${itemClass} ${itemActiveClass}`; | ||
}; | ||
return `${itemClass} ${itemActiveClass}` | ||
} | ||
|
||
const navItemClick = (item: TabProps) => { | ||
if (tabsState) { | ||
// 相同不进行切换 | ||
if (tabsState.active === item.name) { | ||
return; | ||
return | ||
} | ||
|
||
emit('active-tab-change', item.name); | ||
emit('active-tab-change', item.name) | ||
} | ||
}; | ||
} | ||
|
||
const navItemDom = computed(() => { | ||
return navList.value.map((item, index) => { | ||
const curSlotTitle = slotsList.value[index]; | ||
const curSlotTitle = slotsList.value[index] | ||
|
||
return ( | ||
<p | ||
class={getNavItemClass(item)} | ||
onClick={() => { | ||
navItemClick(item); | ||
navItemClick(item) | ||
}} | ||
> | ||
{curSlotTitle.title ? curSlotTitle.title() : item.label} | ||
</p> | ||
); | ||
}); | ||
}); | ||
) | ||
}) | ||
}) | ||
|
||
return () => { | ||
return <div class={containerClass.value}>{navItemDom.value}</div>; | ||
}; | ||
} | ||
}); | ||
return <div class={containerClass.value}>{navItemDom.value}</div> | ||
} | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,64 @@ | ||
import type { | ||
ComputedRef, | ||
ExtractPropTypes, | ||
InjectionKey, | ||
PropType, | ||
InjectionKey | ||
} from 'vue'; | ||
import { TabProps } from './components/tab/tab-types'; | ||
} from 'vue' | ||
import type { TabProps } from './components/tab/tab-types' | ||
|
||
export type ModelValueType = string | number; | ||
export type ModelValueType = string | number | ||
|
||
export type ITabsType = '' | 'card' | 'border-card'; | ||
export type ITabsType = '' | 'card' | 'border-card' | ||
|
||
export type ITabPositionType = 'top' | 'right' | 'bottom' | 'left'; | ||
export type ITabPositionType = 'top' | 'right' | 'bottom' | 'left' | ||
|
||
export type Active = string | number | null; | ||
export type BeforeChangeType = (id: Active) => boolean; | ||
export type Active = string | number | null | ||
export type BeforeChangeType = (id: Active) => boolean | ||
|
||
export interface TabsState { | ||
data?: TabProps[]; | ||
active: string | number; | ||
slots: any[]; | ||
data?: TabProps[] | ||
active: string | number | ||
slots: any[] | ||
} | ||
|
||
export const tabsProps = { | ||
modelValue: { | ||
type: [String, Number] as PropType<ModelValueType>, | ||
default: null | ||
default: null, | ||
}, | ||
type: { | ||
type: String as () => ITabsType, | ||
default: '' | ||
default: '', | ||
}, | ||
customWidth: { | ||
type: String, | ||
default: '' | ||
default: '', | ||
}, | ||
cssClass: { | ||
type: String, | ||
default: '' | ||
default: '', | ||
}, | ||
beforeChange: { | ||
type: Function as PropType<BeforeChangeType>, | ||
default: null | ||
default: null, | ||
}, | ||
tabPosition: { | ||
type: String as () => ITabPositionType, | ||
default: 'top' | ||
} | ||
} as const; | ||
default: 'top', | ||
}, | ||
} as const | ||
|
||
export type TabsProps = ExtractPropTypes<typeof tabsProps>; | ||
export type TabsProps = ExtractPropTypes<typeof tabsProps> | ||
|
||
export interface UseTabsEvent { | ||
onUpdateModelValue: (value: string | number) => void; | ||
onActiveTabChange: (value: string) => void; | ||
onTabChange: (id: string | undefined, type: string) => void; | ||
onUpdateModelValue: (value: string | number) => void | ||
onActiveTabChange: (value: string) => void | ||
onTabChange: (id: string | undefined, type: string) => void | ||
} | ||
|
||
/** KTabs 注入 tab 的 key 值 */ | ||
export const tabsInjectionKey: InjectionKey<TabsState> = Symbol('CTabs'); | ||
export const tabsInjectionKey: InjectionKey<TabsState> = Symbol('CTabs') | ||
|
||
export interface UseTabsRender { | ||
tabsClasses: ComputedRef<Record<string, boolean>>; | ||
tabsClasses: ComputedRef<Record<string, boolean>> | ||
} |
Oops, something went wrong.