feat(tabs): 新增 tabPosition 属性, 更改选项卡位置

This commit is contained in:
sight 2022-03-30 22:07:15 +08:00
parent dc3d0c5a60
commit 6d5960cdb5
3 changed files with 126 additions and 10 deletions

View File

@ -42,7 +42,7 @@ export default {
::: demo
<template>
<lay-tab type="brief" v-model="current2">
<lay-tab type="brief" v-model="current2" tabPosition = "right">
<lay-tab-item title="选项一" id="1"><div style="padding:20px">选项一</div></lay-tab-item>
<lay-tab-item title="选项二" id="2"><div style="padding:20px">选项二</div></lay-tab-item>
</lay-tab>
@ -224,6 +224,45 @@ export default {
:::
::: title 位置设置
:::
::: demo
<template>
<lay-button-group>
<lay-button type="default" size="sm" @click = "tabPosition = 'left'">left</lay-button>
<lay-button type="default" size="sm" @click = "tabPosition = 'right'">right</lay-button>
<lay-button type="default" size="sm" @click = "tabPosition = 'top'">top</lay-button>
<lay-button type="default" size="sm" @click = "tabPosition = 'bottom'">bottom</lay-button>
</lay-button-group>
<lay-tab type="brief" v-model="current7" :tabPosition = "tabPosition">
<lay-tab-item title="选项一" id="1"><div style="padding:20px">选项一</div></lay-tab-item>
<lay-tab-item title="选项二" id="2"><div style="padding:20px">选项二</div></lay-tab-item>
<lay-tab-item title="选项三" id="3"><div style="padding:20px">选项三</div></lay-tab-item>
<lay-tab-item title="选项四" id="4"><div style="padding:20px">选项四</div></lay-tab-item>
</lay-tab>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const current7 = ref("1");
const tabPosition = ref("left");
return {
current2,
tabPosition
}
}
}
</script>
:::
::: title Tab 属性
:::
@ -233,6 +272,7 @@ export default {
| ------------ | ------------------------------------ | ----------------------------------------- |
| v-model | 当前激活 | -- |
| type | 主题样式 | -- |
| tabPosition | 位置 | `top` `bottom` `left` `right` |
| allow-close | 允许关闭 | `true` `false` |
| before-close | `Function`关闭之前的回调钩子函数 | 参数(`id`), `return false` 表示不进行关闭 |
| before-leave | `Function`切换标签之前的回调钩子函数 | 参数(`id`), `return false` 表示不进行切换 |

View File

@ -36,6 +36,63 @@
text-align: center;
cursor: pointer;
}
/** 位置开始 */
.layui-tab.is-right {
display: flex;
flex-direction: row-reverse;
justify-content: space-between
}
.layui-tab-head{
display: inline-block;
}
.layui-tab-title.is-right,
.layui-tab-title.is-left {
height: 100%;
min-width: 60px;
border-bottom-width: 0px;
border-bottom-style: none;
}
.layui-tab-title.is-left li,
.layui-tab-title.is-right li {
border: none;
border-radius: 0;
display: list-item;
}
.layui-tab-head.is-right + .layui-tab-content,
.layui-tab-head.is-left + .layui-tab-content {
height: 100%;
padding: 0 10px;
display: inline-block;
vertical-align: top;
}
.layui-tab-brief > .layui-tab-head.is-left > .layui-tab-more li.layui-this:after,
.layui-tab-brief > .layui-tab-head.is-left > .layui-tab-title .layui-this:after {
border: none;
border-radius: 0;
border-right: 2px solid @global-checked-color;
}
.layui-tab-brief > .layui-tab-head.is-right > .layui-tab-more li.layui-this:after,
.layui-tab-brief > .layui-tab-head.is-right > .layui-tab-title .layui-this:after {
border: none;
border-radius: 0;
border-left: 2px solid @global-checked-color;
}
// .layui-tab-title.is-right li{
// border-left: 2px solid @global-neutral-color-6;
// }
// .layui-tab-title.is-left li{
// border-right: 2px solid @global-neutral-color-6;
// }
/** 位置结束*/
.layui-tab-title li a {
display: block;
@ -137,18 +194,18 @@
color: #fff;
}
.layui-tab-brief > .layui-tab-title .layui-this {
.layui-tab-brief > .layui-tab-head > .layui-tab-title .layui-this {
color: @global-primary-color;
}
.layui-tab-brief > .layui-tab-more li.layui-this:after,
.layui-tab-brief > .layui-tab-title .layui-this:after {
.layui-tab-brief > .layui-tab-head > .layui-tab-more li.layui-this:after,
.layui-tab-brief > .layui-tab-head > .layui-tab-title .layui-this:after {
border: none;
border-radius: 0;
border-bottom: 2px solid @global-checked-color;
}
.layui-tab-brief[overflow] > .layui-tab-title .layui-this:after {
.layui-tab-brief[overflow] > .layui-tab-head > .layui-tab-title .layui-this:after {
top: -1px;
}

View File

@ -18,10 +18,13 @@ import {
watch,
} from "vue";
export type tabPositionType = "top" | "bottom" | "left" | "right" ;
export interface LayTabProps {
type?: string;
modelValue: string;
allowClose?: boolean;
tabPosition?: tabPositionType;
beforeClose?: Function;
beforeLeave?: Function;
}
@ -42,7 +45,9 @@ const setItemInstanceBySlot = function (nodeList: VNode[]) {
});
};
const props = defineProps<LayTabProps>();
const props = withDefaults(defineProps<LayTabProps>(), {
tabPosition: "top"
});
const emit = defineEmits(["update:modelValue", "change", "close"]);
@ -93,14 +98,26 @@ provide("slotsChange", slotsChange);
<template>
<div
class="layui-tab"
:class="[type ? 'layui-tab-' + type : '']"
:class="[type ? 'layui-tab-' + type : '',
props.tabPosition ? `is-${tabPosition}` : '']"
v-if="active"
>
<ul class="layui-tab-title">
<div v-if="tabPosition === 'bottom'" class="layui-tab-content">
<slot></slot>
</div>
<div :class="[
'layui-tab-head',
props.tabPosition ? `is-${tabPosition}` : ''
]">
<ul :class="[
'layui-tab-title',
props.tabPosition ? `is-${tabPosition}` : ''
]">
<li
v-for="(children, index) in childrens"
:key="children"
:class="[children.props.id === active ? 'layui-this' : '']"
:class="[children.props.id === active ? 'layui-this' : '',]"
@click.stop="change(children.props.id)"
>
{{ children.props.title }}
@ -111,7 +128,9 @@ provide("slotsChange", slotsChange);
></i>
</li>
</ul>
<div class="layui-tab-content">
</div>
<div v-if="tabPosition != 'bottom'" class="layui-tab-content">
<slot></slot>
</div>
</div>