vue 自定义tag封装组件,可左右切换直接调用可用

10 篇文章 0 订阅
3 篇文章 0 订阅

vue 自定义tag封装组件,可左右切换直接调用可用

效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

子组件

<template>
  <div class="tag-box">
    <div class="tag-list">
      <ul ref="tagList" :style="{ left: -nowLeft + 'px' }">
        <li
          v-for="(item, index) in list"
          :key="index"
          :ref="'li' + index"
          @click="onClickActive(item)"
        >
          <span class="tag" :class="{ 'tag-active': id === item.id }">
            {{ item.title }}
          </span>
        </li>
      </ul>
    </div>
    <i
      type="left"
      class="el-icon-caret-left"
      v-show="showLf"
      @click="handleLeft"
    />
    <i
      type="right"
      class="el-icon-caret-right"
      v-show="showRt"
      @click="handleRight"
    />
  </div>
</template>

<script>
export default {
  props: {
    list: Array,
  },
  data() {
    return {
      id: 0,
      nowNum: 0, // 滚动了几次
      showLf: false, // 左侧按钮 显隐
      showRt: false, // 右侧按钮 显隐
      allWidth: 0, // 内容总宽
      nowLeft: 0,
      nowIndex: 0, // 显示部分的第一个index
    };
  },
  methods: {
    onClickActive(data) {
      this.id = data.id;
      this.$emit("onclose", data);
    },
    handleLeft() {
      if (this.nowLeft > 0) {
        this.nowNum--;
        this.showRt = true;
        if (this.nowNum > 0) {
          let nw = 0;
          for (let j = this.list.length; j >= 0; j--) {
            if (j < this.nowIndex) {
              nw += this.$refs["li" + j][0].offsetWidth;
              if (nw >= 220) {
                nw -= this.$refs["li" + j][0].offsetWidth;
                this.nowLeft -= nw;
                this.nowIndex = j + 1;
                break;
              }
            }
          }
        } else {
          this.nowLeft = 0;
          this.nowIndex = 0;
          this.showLf = false;
        }
      }
    },
    handleRight() {
      if (this.nowLeft + 220 < this.allWidth) {
        this.nowNum++;
        this.showLf = true;
        let nw = 0;
        for (let i = 0; i < this.list.length; i++) {
          if (i >= this.nowIndex) {
            nw += this.$refs["li" + i][0].offsetWidth;
            if (nw > 220) {
              nw -= this.$refs["li" + i][0].offsetWidth;
              this.nowLeft += nw;
              this.nowIndex = i;
              break;
            }
          }
        }
        if (this.nowLeft + 220 >= this.allWidth) {
          this.showRt = false;
        }
      }
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.allWidth = this.$refs.tagList.offsetWidth;
      if (this.allWidth > 220) {
        // 220为固定宽度
        this.showRt = true;
      }
    });
  },
};
</script>

<style lang="scss" scoped>
.tag-box {
  width: 260px;
  padding: 0 20px;
  height: 28px;
  position: relative;
  .tag-list {
    width: 220px;
    height: 100%;
    line-height: 32px;
    overflow: hidden;
    position: relative;
    ul {
      transition-duration: 0.3s;
      position: absolute;
      top: 0px;
      left: 0px;
      margin: 0;
      padding: 0;
      display: flex;
      flex-wrap: nowrap;
      li {
        white-space: nowrap;
        display: inline-block;
        white-space: nowrap;
        padding: 0 10px;
      }
      li:first-child {
        padding-left: 0;
      }
      li:last-child {
        padding-right: 0;
      }
    }
    .tag {
      cursor: pointer;
      display: inline-block;
      height: 28px;
      // line-height: 28px;
      transition: border-color 0.2s;
      font-size: 14px;
      &:hover {
        color: #1890ff;
      }
    }
    .tag-active {
      color: #1890ff;
      border-bottom: 2px solid #1890ff;
    }
  }
  .el-icon-caret-left {
    cursor: pointer;
    line-height: 28px;
    position: absolute;
    left: 5px;
    top: 2px;
  }
  .el-icon-caret-right {
    line-height: 28px;
    cursor: pointer;
    position: absolute;
    right: 5px;
    top: 2px;
  }
}
</style>

父组件

<template>
  <div class="app-container">
	  <Tags :list="list" @onclose="onClickActive"></Tags>
  </div>
</template>	  

<script>
import Tags from "../../components-demo/Tags";
export default {
  components: {
    Tags
  },
  data() {
    return {
      list: [
        { id: 0, title: "区域分组", name: "qyfz" },
        { id: 1, title: "移动设备", name: "ydsb" },
        { id: 2, title: "业务分组", name: "ywfz" },
        { id: 3, title: "电压分组", name: "dyfz" },
        { id: 4, title: "我的视图", name: "wdst" },
      ]
    };
  },
  methods: {
    //子组件回调方法
    onClickActive(data) {
      let id = data.id;
      this.activeName = data.name;
      if (id == 0) {
      //具体的业务实现
      } else if (id == 1) {
	  //具体的业务实现

      }
    },
   }
};
</script>

但也要根据实际的开发需求修改,当做记录也希望帮到有需要的你。

寄语

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值