zoukankan      html  css  js  c++  java
  • vue3 封装简单的 tabs 切换组件

    背景:公司项目要求全部换成 vue3 ,而且也没有应用像 element-ui 一类的UI组件,用到的公共组件都是根据项目需求封装的,下面是使用vue3实现简单的tabs组件,我只是把代码分享出来,实现思路如果有需要等我项目不忙了在更,希望大家多提些建议,共同学习共同进步。

    tab-group.vue

    <template>
      <div class="tab-group">
        <!-- tabRef 这块本来是用来实现下划线动态切换特效的,暂时没有写效果 -->
        <div ref="barRef" class="tab-bar" :style="{  widthRef + 'px' }"></div>
        <div ref="titsRef" class="tab-header" layout="row" layout-wrap>
          <div
            ref="titRef"
            :class="[{ active: activeKey == item.props.actKey }, 'tab-nav']"
            v-for="(item, index) in tabTitLists"
            :key="item"
            @click="onTabClick($event, item, index)"
          >
            {{ item.props.label }}
          </div>
        </div>
        <div class="tab-panel">
          <slot></slot>
        </div>
      </div>
    </template>
    <script>
    import { ref, onMounted, provide } from "vue";
    export default {
      props: {
        defaultKey: {
          type: String,
          default: "1",
        },
      },
      setup(props, context) {
        const tabTitLists = context.slots.default();
        let activeKey = ref(props.defaultKey); //当前key
        provide("activeKey", activeKey);
    
        const barRef = ref(null);
        const titRef = ref(null);
        let widthRef = ref();
        onMounted(() => {
          // 设置状态线初始化宽度
          widthRef.value = titRef.value.clientWidth;
        });
        function onTabClick(event, tab, index) {
          activeKey.value = tab.props.actKey;
        }
        return {
          tabTitLists,
          barRef,
          titRef,
          widthRef,
          onTabClick,
          activeKey,
        };
      },
    };
    </script>
    <style scoped lang="less">
    .tab-group {
      // .tab-bar {
      //   position: absolute;
      //   left: 0;
      //   border-bottom: 2px solid #409eff;
      // }
      .tab-header {
        &:after {
          content: "";
           100%;
          border-bottom: 2px solid #ddd;
        }
      }
      .tab-nav {
        color: #5c5c5c;
        font-size: 14px;
        line-height: 40px;
        display: inline-block;
        margin-right: 3em;
        cursor: pointer;
        border-bottom: 2px solid transparent;
        &.active {
          color: #2f5cd5;
          border-bottom-color: #2f5cd5;
        }
      }
      .tab-panel{
        padding: 15px;
      }
    }
    </style>
    

    tab-panel.vue

    <template>
      <div v-show="actKey == activeKey">
        <slot></slot>
      </div>
    </template>
    <script>
    import { ref, inject } from "vue";
    export default {
      props: {
        actKey: {
          type: String,
          default: "1",
        },
        label: {
          type: String,
          default: "全部",
        },
      },
    
      setup() {
        let activeKey = ref();
        activeKey = inject("activeKey");
        return { activeKey };
      },
    };
    </script>
    

    应用

    <template>
      <div>
        <tab-group defaultKey="1">
          <tab-panel label="进行中" actKey="1">进行中-内容</tab-panel>
          <tab-panel label="已结束" actKey="2">已结束-内容</tab-panel>
          <tab-panel label="全部" actKey="3">全部带-内容</tab-panel>
        </tab-group>
      </div>
    </template>
    <script>
    import tabGroup from "../common/tabs/tab-group.vue";
    import tabPanel from "../common/tabs/tab-panel.vue";
    export default {
      components: {
        tabPanel,
        tabGroup,
      },
      setup(props, context) {
        return {};
      },
    };
    </script>
    
    生活中不可能到处顺利,包括工作!
  • 相关阅读:
    XmlDocument.selectNodes() and selectSingleNode()的xpath的学习资料
    config相关操作(转)
    网站存储session的方案
    VS2015 C#6.0 中的那些新特性(转自http://www.cnblogs.com/henryzhu/p/new-feature-in-csharp-6.html)
    ERROR L105: PUBLIC REFERS TO IGNORED SEGMENT 的解决办法
    关于C51内的code,idata,xdata
    KeilC51使用详解 (三)
    KeilC51使用详解 (二)
    KeilC51使用详解 (一)
    变量初始化
  • 原文地址:https://www.cnblogs.com/tizi/p/15038009.html
Copyright © 2011-2022 走看看