Skip to content

Commit

Permalink
fix(ui/tabs ui/tabs-items): 优化视图切换 增加tabs垂直布局支持
Browse files Browse the repository at this point in the history
affects: @varlet/ui
  • Loading branch information
haoziqaq committed Jan 8, 2021
1 parent 5282655 commit 1f032ae
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 95 deletions.
2 changes: 1 addition & 1 deletion packages/varlet-ui/src/icon/example/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default defineComponent({
onMounted(() => {
const clipboard = new Clipboard('.example__icon', {
text(trigger) {
text(trigger: any) {
const iconName = trigger.getAttribute('data-clipboard-text')
return `<var-icon name="${iconName}" />`
}
Expand Down
2 changes: 1 addition & 1 deletion packages/varlet-ui/src/tab-item/TabItem.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<transition :name="transitionName" @after-leave="resetTransitionHeight">
<transition :name="transitionName" @after-enter="resetTransitionHeight">
<div class="var-tab-item" ref="tabItemEl" v-show="show">
<slot />
</div>
Expand Down
6 changes: 3 additions & 3 deletions packages/varlet-ui/src/tab/Tab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
class="var-tab var--box"
ref="tabEl"
v-ripple="{ disabled }"
:class="[computeColorClass(), `var-tab--${direction}`]"
:class="[computeColorClass(), `var-tab--${itemDirection}`]"
:style="{
color: computeColorStyle(),
}"
Expand Down Expand Up @@ -40,7 +40,7 @@ export default defineComponent({
bindParent(tabProvider)
const { onTabClick, active, activeColor, inactiveColor, disabledColor, direction, resize } = tabsProvider
const { onTabClick, active, activeColor, inactiveColor, disabledColor, itemDirection, resize } = tabsProvider
const computeColorStyle = () => {
return props.disabled
Expand Down Expand Up @@ -75,7 +75,7 @@ export default defineComponent({
active,
activeColor,
inactiveColor,
direction,
itemDirection,
computeColorStyle,
computeColorClass,
handleClick,
Expand Down
3 changes: 2 additions & 1 deletion packages/varlet-ui/src/tab/tab.less
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
padding: 0 @tab-padding;
font-size: @font-size-md;
color: @tab-color;
overflow: hidden;

&--active {
color: @tab-active-color;
Expand All @@ -31,7 +32,7 @@
color: @tab-disabled-color
}

&--horizental {
&--horizontal {
flex-direction: row;
height: @tab-horizontal-height;
}
Expand Down
17 changes: 7 additions & 10 deletions packages/varlet-ui/src/tabs-items/TabsItems.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { useChildren, useAtChildrenCounter } from '../utils/components'
import { TABS_ITEMS_BIND_TAB_ITEM_KEY, TabsItemsProvider, TABS_ITEMS_COUNT_TAB_ITEM_KEY } from './provide'
import { props } from './props'
import { TabItemProvider } from '../tab-item/provide'
import { debounce, isNumber } from '../utils/shared'
import { isNumber } from '../utils/shared'
export default defineComponent({
name: 'VarTabsItems',
Expand All @@ -30,9 +30,9 @@ export default defineComponent({
)
const { length } = useAtChildrenCounter(TABS_ITEMS_COUNT_TAB_ITEM_KEY)
const resetTransitionHeight = debounce(() => {
transitionHeight.value = 'auto'
}, 1000)
const resetTransitionHeight = () => {
transitionHeight.value = 'auto'
}
const matchName = (active: number | string | undefined): TabItemProvider | undefined => {
return tabItemProviders.find(({ name }: TabItemProvider) => active === name.value)
Expand Down Expand Up @@ -92,16 +92,13 @@ export default defineComponent({
return
}
const { element: oldElement, index: oldIndex } = oldActiveTabItemProvider
const { element: newElement, index: newIndex } = newActiveTabItemProvider
const { index: oldIndex } = oldActiveTabItemProvider
const { element, index: newIndex } = newActiveTabItemProvider
tabItemProviders.forEach(({ transition }) => transition(newIndex.value, oldIndex.value))
nextTick().then(() => {
transitionHeight.value = `${Math.max(
(newElement.value as HTMLElement).offsetHeight,
(oldElement.value as HTMLElement).offsetHeight
)}px`
transitionHeight.value = `${(element.value as HTMLElement).offsetHeight}px`
})
}
)
Expand Down
60 changes: 46 additions & 14 deletions packages/varlet-ui/src/tabs/Tabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,33 @@
<component :is="sticky ? 'var-sticky' : Transition" :offset-top="sticky ? offsetTop : null">
<div
class="var-tabs var--box"
:class="[`var-tabs--${direction}`, `var-elevation--${elevation}`, fixedBottom ? 'var-tabs--fixed-bottom' : null]"
:class="[
`var-tabs--item-${itemDirection}`,
`var-elevation--${elevation}`,
`var-tabs--layout-${layoutDirection}-padding`,
fixedBottom ? 'var-tabs--fixed-bottom' : null
]"
:style="{
background: color,
}"
v-bind="$attrs"
>
<div class="var-tabs__tab-wrap" ref="scrollerEl" :class="[scrollable ? 'var-tabs--scrollable' : null]">
<div
class="var-tabs__tab-wrap"
ref="scrollerEl"
:class="[
scrollable ? `var-tabs--layout-${layoutDirection}-scrollable` : null,
`var-tabs--layout-${layoutDirection}`
]">
<slot />

<div
class="var-tabs__indicator"
:class="[`var-tabs--layout-${layoutDirection}-indicator`]"
:style="{
width: indicatorWidth,
height: indicatorSize,
transform: `translateX(${indicatorX})`,
width: layoutDirection === 'horizontal' ? indicatorWidth : indicatorSize,
height: layoutDirection === 'horizontal' ? indicatorSize : indicatorHeight,
transform: layoutDirection === 'horizontal' ? `translateX(${indicatorX})` : `translateY(${indicatorY})`,
background: indicatorColor || activeColor,
}"
></div>
Expand All @@ -43,14 +55,18 @@ export default defineComponent({
props,
setup(props) {
const indicatorWidth: Ref<string> = ref('0px')
const indicatorHeight: Ref<string> = ref('0px')
const indicatorX: Ref<string> = ref('0px')
const indicatorY: Ref<string> = ref('0px')
const scrollable: Ref<boolean> = ref(false)
const scrollerEl: Ref<HTMLElement | null> = ref(null)
const active: ComputedRef<number | string> = computed(() => props.active)
const activeColor: ComputedRef<string | undefined> = computed(() => props.activeColor)
const inactiveColor: ComputedRef<string | undefined> = computed(() => props.inactiveColor)
const disabledColor: ComputedRef<string | undefined> = computed(() => props.disabledColor)
const direction: ComputedRef<string> = computed(() => props.direction)
const itemDirection: ComputedRef<string> = computed(() => props.itemDirection)
const { childProviders: tabProviders, bindChildren } = useChildren<TabsProvider, TabProvider>(TABS_BIND_TAB_KEY)
const { length } = useAtChildrenCounter(TABS_COUNT_TAB_KEY)
Expand Down Expand Up @@ -89,8 +105,13 @@ export default defineComponent({
}
const moveIndicator = ({ element }: TabProvider) => {
indicatorWidth.value = `${element.value?.offsetWidth}px`
indicatorX.value = `${element.value?.offsetLeft}px`
if (props.layoutDirection === 'horizontal') {
indicatorWidth.value = `${element.value?.offsetWidth}px`
indicatorX.value = `${element.value?.offsetLeft}px`
} else {
indicatorHeight.value = `${element.value?.offsetHeight}px`
indicatorY.value = `${element.value?.offsetTop}px`
}
}
const scrollToCenter = ({ element }: TabProvider) => {
Expand All @@ -100,11 +121,20 @@ export default defineComponent({
const scroller: HTMLElement = scrollerEl.value as HTMLElement
const el = element.value as HTMLElement
const left: number = el.offsetLeft + el.offsetWidth / 2 - scroller.offsetWidth / 2
scroller.scrollTo({
left,
behavior: 'smooth',
})
if (props.layoutDirection === 'horizontal') {
const left: number = el.offsetLeft + el.offsetWidth / 2 - scroller.offsetWidth / 2
scroller.scrollTo({
left,
behavior: 'smooth',
})
} else {
const top: number = el.offsetTop + el.offsetHeight / 2 - scroller.offsetHeight / 2
scroller.scrollTo({
top,
behavior: 'smooth',
})
}
}
const resize = () => {
Expand All @@ -123,7 +153,7 @@ export default defineComponent({
activeColor,
inactiveColor,
disabledColor,
direction,
itemDirection,
resize,
onTabClick,
}
Expand All @@ -139,7 +169,9 @@ export default defineComponent({
return {
indicatorWidth,
indicatorHeight,
indicatorX,
indicatorY,
scrollable,
scrollerEl,
Transition,
Expand Down
125 changes: 76 additions & 49 deletions packages/varlet-ui/src/tabs/example/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
<app-type>垂直布局</app-type>
<var-tabs
style="width: 345px"
direction="vertical"
item-direction="vertical"
color="rgb(98,0,234)"
active-color="#fff"
inactive-color="rgb(193,155,247)"
Expand All @@ -67,7 +67,7 @@
active-color="#fff"
inactive-color="rgb(193,155,247)"
indicator-size="0"
direction="vertical"
item-direction="vertical"
fixed-bottom
:elevation="4"
v-model:active="activeBottom"
Expand All @@ -87,9 +87,31 @@
</var-tab>
</var-tabs>

<app-type>视图联动</app-type>
<div class="container">
<var-tabs
style="height: 300px; flex-shrink: 0"
color="rgb(98,0,234)"
active-color="#fff"
inactive-color="rgb(193,155,247)"
layout-direction="vertical"
:elevation="2"
v-model:active="activeRelation"
@change="handleChange"
>
<var-tab v-for="i in list2" :key="i.id">
{{ i.name }}
</var-tab>
<var-tab :key="100">长文字</var-tab>
</var-tabs>
<var-tabs-items style="margin-left: 10px" v-model:active="activeRelation">
<var-tab-item v-for="i in list2" :key="i.id"> {{ i.name }}视图 </var-tab-item>
<var-tab-item :key="100">测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字</var-tab-item>
</var-tabs-items>
</div>

<app-type>视图联动</app-type>
<var-tabs
ref="s"
style="width: 345px"
color="rgb(98,0,234)"
active-color="#fff"
Expand All @@ -101,16 +123,18 @@
<var-tab v-for="i in list2" :key="i.id">
{{ i.name }}
</var-tab>
<var-tab :key="100">长文字</var-tab>
</var-tabs>

<var-tabs-items ref="s1" style="margin-top: 10px" v-model:active="activeRelation">
<var-tabs-items style="margin-top: 10px" v-model:active="activeRelation">
<var-tab-item v-for="i in list2" :key="i.id"> {{ i.name }}视图 </var-tab-item>
<var-tab-item :key="100">测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字测试长文字</var-tab-item>
</var-tabs-items>

<var-button @click="push" style="margin-bottom: 10px">push</var-button>
<var-button @click="unshift" style="margin-bottom: 10px">unshift</var-button>
<var-button @click="pop" style="margin-bottom: 10px">pop</var-button>
<var-button @click="shift" style="margin-bottom: 10px">shift</var-button>
<!-- <var-button @click="push" style="margin-bottom: 10px">push</var-button>-->
<!-- <var-button @click="unshift" style="margin-bottom: 10px">unshift</var-button>-->
<!-- <var-button @click="pop" style="margin-bottom: 10px">pop</var-button>-->
<!-- <var-button @click="shift" style="margin-bottom: 10px">shift</var-button>-->

<app-type>开启粘性布局</app-type>
<var-tabs
Expand Down Expand Up @@ -173,47 +197,44 @@ export default defineComponent({
])
const list2 = reactive<any>([])
setTimeout(() => {
list2.push(
{
id: 1,
name: '瓜瓜',
},
{
id: 2,
name: '咋咋',
},
{
id: 3,
name: '拉拉',
},
{
id: 4,
name: '瓜瓜',
},
{
id: 5,
name: '咋咋',
},
{
id: 6,
name: '拉拉',
},
{
id: 7,
name: '瓜瓜',
},
{
id: 8,
name: '咋咋',
},
{
id: 9,
name: '拉拉',
}
)
}, 2000)
list2.push(
{
id: 1,
name: '瓜瓜',
},
{
id: 2,
name: '咋咋',
},
{
id: 3,
name: '拉拉',
},
{
id: 4,
name: '瓜瓜',
},
{
id: 5,
name: '咋咋',
},
{
id: 6,
name: '拉拉',
},
{
id: 7,
name: '瓜瓜',
},
{
id: 8,
name: '咋咋',
},
{
id: 9,
name: '拉拉',
}
)
const handleChange = (...args: any[]) => {
console.log(...args)
Expand Down Expand Up @@ -263,5 +284,11 @@ export default defineComponent({
* {
box-sizing: border-box;
}
.container {
display: flex;
width: 100%;
margin-top: 20px;
}
}
</style>
Loading

0 comments on commit 1f032ae

Please sign in to comment.