目前只是实现了表面的功能,实际上很多东西都没有实现,后期有时间在优化
模板中
<test-tab v-model="behavior" @tab-change="changTab">
<tab-pane label="账号登录" name="login"> 账号登录内容 </tab-pane>
<tab-pane label="短信登录" name="sms"> 短信登录内容 </tab-pane>
<tab-pane label="微信登录" name="weChat"> 微信登录内容 </tab-pane>
</test-tab>
tab组件
<template>
<div class="login__tab">
<div
:class="[{ active: item.name == modelValue }, `login--item`]"
v-for="item in tabList"
:key="item"
@click="tabClick(item)"
>
<span>{{ item.label }}</span>
</div>
</div>
<div v-for="(item, index) in defaults" :key="item">
<div v-if="item.props.name == modelValue">
<component v-bind:is="defaults[index]" />
</div>
</div>
</template>
<script>
import { reactive, toRefs, defineComponent, onBeforeMount } from "vue";
// import { useRouter } from "vue-router";
export default defineComponent({
name: "App",
components: {},
props: {
modelValue: String,
},
setup(props, context) {
const state = reactive({
tabList: [],
defaults: null,
});
onBeforeMount(() => {
console.log("context.slots.default():", context.slots.default());
state.defaults = context.slots.default();
const tabList = [];
context.slots.default().forEach((item) => {
tabList.push(item.props);
});
state.tabList = tabList;
});
const tabClick = (item) => {
if (item.name == props.modelValue) {
return;
}
context.emit("update:modelValue", item.name);
context.emit("tab-change", item);
};
return {
...toRefs(state),
tabClick,
};
},
});
</script>
<style lang="scss" scoped>
// 登录页面tab
.login__tab {
display: flex;
text-align: center;
.login--item {
flex: 1;
transform: translateY(4px) scale(0.8);
}
.login--item span {
font-size: 24px;
font-weight: 400;
color: #acacac;
text-align: center;
cursor: pointer;
position: relative;
}
.login--item span::before {
content: "";
position: absolute;
height: 12px;
bottom: -5px;
left: 50%;
transform: translateX(-50%);
background: linear-gradient(
180deg,
rgba(0, 166, 255, 0.36470588235294116),
#006cff
);
width: 0;
opacity: 0.1;
}
.login--item.active {
font-weight: 700;
transform: translateY(0) scale(1);
}
.login--item.active span {
color: #006cff;
font-weight: bold;
}
.login--item.active span::before {
width: 100%;
transition: all 0.3s ease-out;
}
}
</style>
tab子组件
<template>
<div>
<!-- {{ label }}--{{ name }} -->
<!-- <slot /> -->
<!-- <component v-bind:is="defaults[0]" /> -->
<slot />
</div>
</template>
<script>
import { reactive, toRefs, defineComponent, onBeforeMount } from "vue";
// import { useRouter } from "vue-router";
export default defineComponent({
name: "App",
components: {},
props: {
label: String,
name: Number,
},
setup(props, context) {
const state = reactive({
defaults: null,
});
onBeforeMount(() => {
state.defaults = context.slots.default();
console.log("tabPanel", context.slots.default());
});
return {
...toRefs(state),
};
},
});
</script>
<style lang="scss" scoped></style>
现在实在没时间优化了,催进度了。。。。。,记录一下方便下次copy优化