🌀(component): 修复 tab 样式

This commit is contained in:
sight 2022-05-31 21:27:04 +08:00
parent f57465d8a0
commit d553e38ab4
2 changed files with 118 additions and 31 deletions

View File

@ -75,15 +75,14 @@
border-bottom-style: none; border-bottom-style: none;
} }
.layui-tab-title.is-left li, .layui-tab-title.is-left li {
.layui-tab-title.is-right li {
border: none;
border-radius: 0;
display: list-item; display: list-item;
margin-right: -1px; margin-right: -1px;
margin-left: -1px;
} }
.layui-tab-title.is-right li{
display: list-item;
margin-left: -1px;
}
.layui-tab-title.is-right { .layui-tab-title.is-right {
border-left: 1px solid var(--global-neutral-color-3); border-left: 1px solid var(--global-neutral-color-3);
@ -93,14 +92,6 @@
border-right: 1px solid var(--global-neutral-color-3); border-right: 1px solid var(--global-neutral-color-3);
} }
.layui-tab-title.is-right .layui-this {
border-left-color: #FFF;
}
.layui-tab-title.is-left .layui-this {
border-right-color: #FFF;
}
.layui-tab-title .layui-this { .layui-tab-title .layui-this {
color: #000; color: #000;
background-color: #fff background-color: #fff
@ -143,7 +134,6 @@
.layui-tab-brief>.layui-tab-head>.layui-tab-title .layui-this:after { .layui-tab-brief>.layui-tab-head>.layui-tab-title .layui-this:after {
border: none; border: none;
border-radius: 0; border-radius: 0;
border-bottom: 2px solid var(--global-checked-color);
} }
.layui-tab-brief>.layui-tab-head.is-right>.layui-tab-title{ .layui-tab-brief>.layui-tab-head.is-right>.layui-tab-title{
@ -157,20 +147,15 @@
top: -1px; top: -1px;
} }
.layui-tab-brief > .layui-tab-head.is-left > .layui-tab-more li.layui-this:after, .layui-tab-brief>.layui-tab-head.is-right>.layui-tab-title li,
.layui-tab-brief > .layui-tab-head.is-left > .layui-tab-title .layui-this:after { .layui-tab-brief>.layui-tab-head.is-left>.layui-tab-title li{
border: none; margin-right: 0px;
border-radius: 0;
border-right: 2px solid var(--global-checked-color);
margin-left: 1px;
} }
.layui-tab-brief > .layui-tab-head.is-right > .layui-tab-more li.layui-this:after, .layui-tab-brief>.layui-tab-head.is-top>.layui-tab-title li,
.layui-tab-brief > .layui-tab-head.is-right > .layui-tab-title .layui-this:after { .layui-tab-brief>.layui-tab-head.is-top>.layui-tab-title li {
border: none; margin-top: 0px;
border-radius: 0; margin-bottom: 0px;
border-left: 2px solid var(--global-checked-color);
margin-right: 1px;
} }
.layui-tab-card { .layui-tab-card {
@ -180,15 +165,32 @@
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.1); box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.1);
} }
.layui-tab-card>.layui-tab-head>.layui-tab-title li { .layui-tab-card>.layui-tab-head>.layui-tab-title.is-top {
margin-top: -1px;
}
.layui-tab-card>.layui-tab-head>.layui-tab-title.is-right,
.layui-tab-card>.layui-tab-head>.layui-tab-title.is-left {
margin-right: -1px; margin-right: -1px;
margin-left: -1px; margin-left: -1px;
} }
.layui-tab-card>.layui-tab-head>.layui-tab-title.is-bottom li {
margin-top: -1px;
}
.layui-tab-card>.layui-tab-head>.layui-tab-title .layui-this:after{
border-radius: 0;
}
.layui-tab-card>.layui-tab-head>.layui-tab-title.is-bottom{
border-top: 1px solid var(--global-neutral-color-3);
margin-bottom: -2px;
}
.layui-tab-card>.layui-tab-head>.layui-tab-title.is-left li, .layui-tab-card>.layui-tab-head>.layui-tab-title.is-left li,
.layui-tab-card>.layui-tab-head>.layui-tab-title.is-right li { .layui-tab-card>.layui-tab-head>.layui-tab-title.is-right li {
margin-top: -1px; margin-top: -1px;
margin-bottom: -1px; margin-bottom: -1px;
} }
.layui-tab-card>.layui-tab-head>.layui-tab-title.is-top .layui-this:after { .layui-tab-card>.layui-tab-head>.layui-tab-title.is-top .layui-this:after {
@ -310,3 +312,39 @@
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
} }
.layui-tab-active-bar{
position: absolute;
bottom: 0px;
left: 0;
height: 1.5px;
background-color: #409eff;
z-index: 2;
transition: transform .3s;
list-style: none;
box-sizing: border-box;
pointer-events: none;
}
.is-top .layui-tab-active-bar{
bottom: 0px;
height: 1.5px;
}
.is-left .layui-tab-active-bar {
left: auto;
right: -1px;
top: 0;
bottom: auto;
width: 1.5px;
}
.is-right .layui-tab-active-bar {
left: -1px;
right: auto;
top: 0;
bottom: auto;
width: 1.5px;
}

View File

@ -16,7 +16,12 @@ import {
Ref, Ref,
ref, ref,
watch, watch,
shallowRef,
onMounted,
nextTick,
CSSProperties,
} from "vue"; } from "vue";
import { useResizeObserver } from '@vueuse/core'
export type tabPositionType = "top" | "bottom" | "left" | "right"; export type tabPositionType = "top" | "bottom" | "left" | "right";
@ -81,6 +86,35 @@ const close = function (index: number, id: any) {
emit("close", id); emit("close", id);
}; };
const activeBarRef = shallowRef<HTMLElement>();
const activeEl = shallowRef<HTMLElement | undefined>();
const tabBarStyle = ref<CSSProperties>()
const getBarStyle = () => {
let offset = 0;
let tabSize = 0;
const sizeName = props.tabPosition === "top" || props.tabPosition === "bottom" ? "width" : "height";
const axis = sizeName === "width" ? "X" : "Y";
const position = axis === 'X' ? 'left' : 'top'
const el = activeEl.value;
if(!el || !el.parentElement) return;
const rect = el.getBoundingClientRect();
const parentRect = el.parentElement?.getBoundingClientRect();
offset = rect[position] - parentRect[position];
tabSize = el.getBoundingClientRect()[sizeName];
return {
[sizeName]: `${tabSize}px`,
transform: `translate${axis}(${offset}px)`,
}
}
const update = () => {
const parentEL = activeBarRef.value?.parentNode;
activeEl.value = parentEL?.querySelector(" .layui-this") as HTMLElement;
tabBarStyle.value = getBarStyle();
}
const containerSize = "";
const navSize = "";
watch( watch(
slotsChange, slotsChange,
function () { function () {
@ -90,6 +124,18 @@ watch(
{ immediate: true } { immediate: true }
); );
watch(
() => [props.modelValue, props.tabPosition, props.type],
async () => {
await nextTick();
update();
}
)
onMounted(() => {
update();
})
provide("active", active); provide("active", active);
provide("slotsChange", slotsChange); provide("slotsChange", slotsChange);
</script> </script>
@ -111,11 +157,13 @@ provide("slotsChange", slotsChange);
props.tabPosition ? `is-${tabPosition}` : '', props.tabPosition ? `is-${tabPosition}` : '',
]" ]"
> >
<div ref="activeBarRef" v-if="type === 'brief'" class="layui-tab-active-bar" :style="tabBarStyle"></div>
<li <li
v-for="(children, index) in childrens" v-for="(children, index) in childrens"
:key="children.props?.id" :key="children.props?.id"
:class="[children.props?.id === active ? 'layui-this' : '']" :class="[children.props?.id === active ? 'layui-this' : '']"
@click.stop="change(children.props?.id)" @click.stop="change(children.props?.id)"
> >
{{ children.props?.title }} {{ children.props?.title }}
<i <i
@ -125,6 +173,7 @@ provide("slotsChange", slotsChange);
></i> ></i>
</li> </li>
</ul> </ul>
</div> </div>
<div class="layui-tab-content"> <div class="layui-tab-content">
<slot></slot> <slot></slot>