一键复制:基于vue实现的tab切换效果

发布于:2024-05-09 ⋅ 阅读:(23) ⋅ 点赞:(0)

需求:顶部栏有切换功能,内容区域随顶部切换而变化

实现效果

如下
在这里插入图片描述

实现代码

组件代码 MoTab.vue

<template>
  <div class="mo-tab">
    <div
      v-for="item in options"
      class="mo-tab__item"
      :class="{
        'mo-tab__item--active': item.value == currentValue,
      }"
      @click="handleChange(item.value)"
    >
      {{ item.label }}
    </div>
  </div>
</template>

<script>
// created at 2024-05-08
export default {
  name: "MoTab",

  props: {
    // 选项
    // eg: [{label: '显示值', value: '真实值'}]
    options: {
      type: Array,
      default: () => {
        return [];
      },
    },

    // 选定值
    value: {
      type: String,
      default: "",
    },
  },

  computed: {
    currentValue: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit("input", val);
      },
    },
  },

  methods: {
    handleChange(value) {
      this.currentValue = value;
      this.$emit("on-change", value);
    },
  },
};
</script>

<style lang="less">
.mo-tab {
  display: flex;
  margin-left: 20px;
}

.mo-tab__item {
  position: relative;
  padding: 0 10px;
  line-height: 30px;
  font-size: 13px;
  color: #666;
  cursor: pointer;
}

.mo-tab__item:hover,
.mo-tab__item--active {
  color: #111;
}

.mo-tab__item--active::before {
  content: "";
  position: absolute;
  height: 2px;
  width: 16px;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  background-color: #6833cf;
}

</style>

使用示例

<template>
  <div class="app">
    <MoTab
      :options="options"
      v-model="value"
      @on-change="handleValueChange"
    ></MoTab>

    <div class="content">
      <p>选定真实值: {{ value }}</p>
      <p>选定显示值: {{ currentLabel }}</p>
    </div>
  </div>
</template>

<script>
// created at 2023-03-31
import MoTab from "./components/MoTab/MoTab.vue";

export default {
  name: "App",

  props: {},

  components: {
    MoTab,
  },

  data() {
    return {
      // 选定值
      value: "1",

      // 选项
      options: [
        {
          value: "1",
          label: "蔬菜",
        },
        {
          value: "2",
          label: "肉类",
        },
        {
          value: "3",
          label: "水果",
        },
      ],
    };
  },

  computed: {
    currentLabel() {
      return this.options.find((item) => item.value === this.value)?.label;
    },
  },

  methods: {
    handleValueChange(value) {
      console.log("value change: ", value);
    },
  },

  created() {},
};
</script>

<style lang="less">
.app {
  width: 200px;
  margin: 0 auto;
  border: 1px solid #ccc;
  padding: 20px;
}

.content {
  margin-top: 20px;
  border-top: 1px solid #ccc;
}
</style>

在线预览

https://mouday.github.io/vue-demo/packages/vue-mo-tab/dist/index.html