vue中多功能tab组件

1.TabGroup.vue

<template>
  <div class="yh-tab-group">
    <el-badge
      :value="item.badge"
      v-for="(item, index) in tabs"
      class="yh-tab-button"
      :class="{'yh-badge-check':item.check,
	   'yh-badge-char':item.charBadge}"
      :key="index"
    >
      <button
        :class="{'yh-selected':selectedIndex === index,
											'yh-primary':selectedIndex === index,
											'yh-closable':closable}"
        class="yh-button"
        @click="onTabClicked(index, $event)"
      >
        {{item.title}}
        <span
          v-if="closable"
          class="yh-tab-close"
          @click="onCloseClicked(index, $event)"
        >X</span>
      </button>
    </el-badge>
  </div>
</template>
<script>
function _create_tab(tab, bf) {
  var t = { data: tab };
  if (typeof tab == "string") {
    t.title = tab;
  } else {
    t.title = tab.title;
    var badge = tab[bf || "badge"];
    if (badge == "check") {
      t.badge = "✓";
      t.check = true;
      t.charBadge = true;
    } else if (badge == "cross") {
      t.badge = "✕";
      t.charBadge = true;
    } else {
      t.badge = badge;
    }
  }
  return t;
}

export default {
  name: "TabGroup",
  data() {
    return {
      selectedIndex: -1,
      tabs: []
    };
  },
  props: ["options", "default", "selectable", "closable", "badgeField"],
  /*watch : {
		 options : function() {
			 this.onOptionUpdated();
		 }
	 },*/
  methods: {
    addTab(tab, select) {
      this.tabs.push(_create_tab(tab, this.badgeField));
      if (select) {
        this.selectedIndex = this.tabs.length - 1;
      }
    },
    onTabClicked(index, e) {
      e.preventDefault();
      e.stopPropagation();
      if (this.selectable !== false) {
        this.selectedIndex = index;
        this.$emit("select", index, this.tabs[index].data);
      }
    },
    onCloseClicked(index, e) {
      e.preventDefault();
      e.stopPropagation();
      this.$emit("close", index, this.tabs[index].data);
    },
    select(index) {
      this.selectedIndex = index;
    },
    selectWith(key, value) {
      var i = this.tabIndex(key, value);
      if (i >= 0) {
        this.select(i, to);
      }
    },
    tabAt(index) {
      if (index >= 0 && index < this.tabs.length) {
        return this.tabs[index].data;
      }
    },
    tabWith(key, value) {
      var i = this.tabIndex(key, value);
      if (i >= 0) {
        return this.tabs[i].data;
      }
    },
    tabIndex(key, value) {
      var tabs = this.tabs;
      for (var i = 0; i < tabs.length; ++i) {
        var d = tabs[i].data;
        if (d && d[key] == value) {
          return i;
        }
      }
      return -1;
    },
    moveTabAt(i, to) {
      var tabs = this.tabs;
      if (
        i >= 0 &&
        i < tabs.length &&
        to >= 0 &&
        to <= tabs.length &&
        to != i &&
        to != i + 1
      ) {
        var e = tabs[i];
        if (to < i) {
          for (var j = i; j > to; --j) {
            tabs[j] = tabs[j - 1];
          }
        } else {
          if (to == tabs.length) {
            to = tabs.length - 1;
          }
          for (var j = i; j < to; ++j) {
            tabs[j] = tabs[j + 1];
          }
        }
        this.$set(tabs, to, e);
      }
    },
    moveTabWith(key, value, to) {
      var i = this.tabIndex(key, value);
      if (i >= 0) {
        this.moveTabAt(i, to);
      }
    },
    removeWith(key, value) {
      var i = this.tabIndex(key, value);
      if (i >= 0) {
        this.remove(key, value);
      }
    },
    remove(index, select) {
      var tabs = this.tabs;
      var item;
      var n = tabs.length;
      if (index >= 0 && index < n) {
        item = tabs.splice(index, 1);
        --n;
        if (n == 0) {
          this.selectedIndex = -1;
        } else if (select >= 0 && select < n) {
          this.selectedIndex = select;
        }
      }
      return item;
    },
    clear() {
      this.tabs = [];
      this.selectedIndex = -1;
    },
    updateTab(opt) {
      debugger;
      var i = this.options.indexOf(opt);
      if (i >= 0) {
        tabs[i] = _create_tab(opt, this.badgeField);
      }
    },
    onOptionUpdated() {
      var tabs = [];
      var opts = this.options;
      var bf = this.badgeField;
      if (opts) {
        opts.forEach(function(opt) {
          tabs.push(_create_tab(opt, bf));
        });
      }
      this.tabs = tabs;
    }
  },
  created() {
    this.$watch(
      "options",
      function() {
        this.onOptionUpdated();
      },
      { deep: true }
    );
    this.onOptionUpdated();
    if (this.default >= 0) {
      this.selectedIndex = this.default;
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

2.TabGroupDemo.vue

<template>
  <div class="yh-page">
    <h1>TabGroup演示</h1>
    <div class="desc">Demo源代码:
      <code>/examples/components/modules/TabGroupDemo.vue</code>
    </div>
    <div class="yh-block">
      <yh-tab-group
        @select="onTabSelected"
        :options="options"
        :default="0"
        :closable="true"
        ref="tg1"
        @close="close"
      ></yh-tab-group>
      <yh-tab-group
        @select="onTabSelected2"
        class="yh-dash-border"
        :options="options2"
        badgeField="value"
        ref="tg2"
        :default="0"
      ></yh-tab-group>
    </div>
  </div>
</template>
<script>
import tabgroup from "../comcompont/TabGroup";
export default {
  name: "TabGroupDemo",
  data() {
    return {
      options: [
        "刷新",
        "添加",
        "移动",
        "查询",
        "清空",
        "Select",
        "Update Title"
      ],
      options2: [
        { title: "基金", value: 0 },
        { title: "理财", value: 1 },
        { title: "保险", value: 2 },
        { title: "贵金属", value: 3 },
        { title: "保险1", value: 4 },
        { title: "贵金属1", value: 5 }
      ],
      options3: [
        "基金",
        { title: "理财", value: 2 },
        { title: "保险", value: "check" },
        { title: "贵金属", value: "cross" },
        "国债",
        "银行卡",
        "存单",
        "产品组合"
      ]
    };
  },
  methods: {
    close(index) {
      this.$refs.tg1.remove(index);
    },
    onTabSelected: function(index, data) {
      var tg2 = this.$refs.tg2;
      switch (index) {
        case 0:
          this.options2 = this.options3;
          break;
        case 1:
          tg2.addTab("New Tab", true);
          break;
        case 2:
          tg2.moveTabWith("value", 5, 0, true);
          break;
        case 3:
          alert("tab " + JSON.stringify(tg2.tabWith("value", 2)));
          break;
        case 4:
          tg2.clear();
          break;
        case 5:
          tg2.select(3);
          break;
        case 6:
          this.options2[1].title = "Test";
          break;
      }
    },
    onTabSelected2: function(index, data) {}
  },
  components: {
    "yh-tab-group": tabgroup,
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scope>
</style>

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 根据提供的代码,这是一个使用Vue实现的动态tab切换加载不同组件的功能。\[1\]在主页面代码,通过点击不同的项来加载不同的子组件。主页面导入了child1.vue, child2.vue, child3.vue三个小模块,并在点击事件通过tabChange方法来切换当前显示的组件。\[1\]在Test.vue代码,使用了router-link来展示tab项,并通过isActive方法来判断当前项是否为选状态。\[2\]在子组件child1.vue,只是简单地展示了一个文本信息。\[3\] 所以,这个功能实现了一个动态的tab页,可以根据用户的点击来加载不同的子组件。 #### 引用[.reference_title] - *1* *3* [vue 实现tab切换动态加载不同的组件](https://blog.csdn.net/yshusencsdn/article/details/102718007)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [vue点击菜单实现多标签页tab,打开关闭多个页面](https://blog.csdn.net/qq_39037897/article/details/122600554)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值