tabs组件封装

Tabs组件封装

封装到tabs组件,最简单的方式肯定是写几个div,内容和导航栏写在一起。例如

  <div :class="{'active':index===1}">1</div>
  <div :class="{'active':index===2}">2</div>
  <div :class="{'active':index===3}">3</div>
  <div :class="{'active':index===4}">4</div>

但这样,逻辑代码和业务逻辑就没有彻底分开。因此,实现tab栏的最佳逻辑就是逻辑代码和业务逻辑相隔离。采用Element-plus的那种方法:

<el-tabs type="border-card">
  <el-tab-pane label="用户管理">用户管理</el-tab-pane>
  <el-tab-pane label="配置管理">配置管理</el-tab-pane>
  <el-tab-pane label="角色管理">角色管理</el-tab-pane>
  <el-tab-pane label="定时任务补偿">定时任务补偿</el-tab-pane>
</el-tabs>

下面来自己手动封装一个.

该组件封装的几个关键点:

  1. provideinject。至于为什么不用props传递,因为props会导致数据出现响应式丢失。
  2. useSlots获取到所有插槽的内容信息。

Tabs组件

<template>
  <!-- 我是tabs页面 -->
  <div class="tabsShow">
    <div
      class="item"
      v-for="(item, index) in childrenProps"
      :key="index"
      @click="handleSelectTab(item.name)"
      :class="[{ active: active === item.name }]"
    >
      {{ item.name }}
    </div>
  </div>

  <div class="slot"><slot></slot></div>
</template>

<script setup>
import { useSlots, onMounted, ref, provide } from "vue";
const props = defineProps(["modelValue"]);
const emit = defineEmits(["handleClick"]);
const slots = useSlots();
const childrenProps = ref([]); // 子组件的标题
const active = ref(""); // 下标
provide("active", active);
const handleSelectTab = (name) => {
  active.value = name;

  emit("handleClick", active.value);
};
onMounted(() => {
  console.log(slots.default());
  slots.default().forEach((item, index) => {
    childrenProps.value.push(item.props);
  });
  active.value = slots.default()[0].props.name;
  console.log(childrenProps.value);
});
console.log(props);
</script>
<style lang="scss" scoped>
div {
  box-sizing: border-box;
}
.tabsShow {
  cursor: pointer;
  display: flex;
  height: 50px;
  border: 1px solid rgba($color: #000000, $alpha: 0.1);
  justify-content: flex-start;
  .item {
    border-left: 1px solid rgba(0, 0, 0, 0.1);
    border-right: 1px solid rgba($color: #000000, $alpha: 0.1);
    padding: 5px 10px;
    height: 100%;
    width: fit-content;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .active {
    background-color: rgba(0, 0, 0, 0.15);
  }
}
.slot {
}
</style>

pane组件

<template>
  <div v-if="activeName == name"><slot></slot></div>
</template>

<script setup>
import { inject, defineProps, ref, watch } from "vue";
const activeName = inject("active");
console.log(activeName);
const props = defineProps(["label", "name"]);
</script>
<style lang="scss" scoped></style>

对此,基本的功能已经完成。如果有样式的需求,可以继续在上面进行封装。

在 React 中封装 Ant Design 的 Tabs 组件,可以将 Tabs 组件包装成一个自定义组件,方便在项目中复用。以下是一个简单的封装示例: ```javascript import React, { useState } from "react"; import { Tabs } from "antd"; const { TabPane } = Tabs; function CustomTabs(props) { const [activeKey, setActiveKey] = useState(props.defaultActiveKey); const handleTabChange = (key) => { setActiveKey(key); if (props.onChange) { props.onChange(key); } }; return ( <Tabs activeKey={activeKey} onChange={handleTabChange} tabBarExtraContent={props.extraContent} > {props.tabPanes.map((pane) => ( <TabPane tab={pane.tab} key={pane.key}> {pane.content} </TabPane> ))} </Tabs> ); } export default CustomTabs; ``` 在上面的代码中,我们定义了一个 `CustomTabs` 组件,它接收以下 props: - `defaultActiveKey`: 默认选中的标签页 key; - `extraContent`: 标签页导航栏右侧的额外内容; - `tabPanes`: 标签页的配置数组,每个配置对象包含 `tab` 和 `key` 两个属性,分别表示标签页的标题和 key 值,以及 `content` 属性,表示标签页的内容; - `onChange`: 标签页切换时的回调函数。 在组件内部,我们使用 `useState` Hook 来管理当前选中的标签页 key,使用 `handleTabChange` 函数处理标签页切换事件,并将其传递给 Ant Design 的 Tabs 组件。同时,我们根据传入的 `tabPanes` 配置数组,动态生成标签页和对应的内容。 我们可以在项目中使用这个组件,如下所示: ```javascript import React from "react"; import CustomTabs from "./CustomTabs"; function MyComponent() { const tabPanes = [ { tab: "Tab 1", key: "1", content: <div>Content of Tab Pane 1</div>, }, { tab: "Tab 2", key: "2", content: <div>Content of Tab Pane 2</div>, }, { tab: "Tab 3", key: "3", content: <div>Content of Tab Pane 3</div>, }, ]; return ( <CustomTabs defaultActiveKey="1" extraContent={<div>Extra content</div>} tabPanes={tabPanes} onChange={(key) => console.log(`Tab ${key} is clicked.`)} /> ); } ``` 在上面的代码中,我们传递了一些配置参数给 `CustomTabs` 组件,它会根据这些参数渲染出标签页导航栏和对应的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值