vue+elementUI实现的标签选择及新建标签

241 阅读1分钟

实现如下图所示的一个标签选择组件。

图1:标签选中时的效果
在这里插入图片描述

图2:标签新建时的效果
在这里插入图片描述

实现

tagSelect.vue

<template>
  <div class="sys-tag">
    <el-popover :visible-arrow="false" :offset="-50" width="600" v-model="tagVisible">
      <div style="padding: 10px">
        <el-tag class="select-tag pointer" :color="tag.color" effect="dark" closable v-for="(tag, index) in selected"
          :key="index" @close="closeLabel(index)">{{ tag.labelName }}</el-tag>
        <span style="color: #aaa" v-if="selected">还可以添加{{ 6 - selected.length }}个标签</span>
        <div style="padding: 10px 0">
          <el-input v-model="labelName" clearable style="width: 300px" placeholder="添加标签"
            @keyup.enter.native="addLabel"></el-input>
        </div>

        <div v-show="labelName">
          <div style="padding: 10px">选择一个颜色</div>
          <div @click="color = item" class="color-item pointer" :style="'background-color:' + item"
            v-for="(item, index) in colorList" :key="index">
            <i v-if="color == item" class="el-icon-check pos-center"></i>
          </div>
          <div style="clear: both; padding: 10px">
            <el-button type="primary" @click="addLabel">新建</el-button>
          </div>
        </div>

        <div v-show="!labelName" style="max-height: 250px; height: auto; overflow-y: auto">
          <el-tag class="select-tag pointer" v-for="(item, index) in tags" :key="index" :color="item.color" effect="dark"
            :hit="false" @click="selectLabel(item)">{{ item.labelName }}</el-tag>
        </div>
      </div>

      <div slot="reference" v-show="!readonly" style="display: inline">
        <el-tag class="select-tag pointer" :color="tag.color" effect="dark" v-for="tag in selected" :key="tag.labelID">{{
          tag.labelName }}</el-tag>
        <el-button icon="el-icon-circle-plus-outline" size="mini" type="text">添加标签</el-button>
      </div>
    </el-popover>
    <template v-if="readonly">
      <el-tag class="select-tag" :color="tag.color" effect="dark" v-for="tag in labList" :key="tag.labelID">{{
        tag.labelName }}</el-tag>
      <el-tag class="select-tag" v-if="labList && 0 == labList.length" type="info">暂无标签</el-tag>
    </template>
  </div>
</template>
<script>
export default {
  props: {
    readonly: {
      type: Boolean,
      default: false
    },
    labList: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      color: "#F6C600",
      labelName: "",
      tagVisible: false,
      tags: [
        { labelID: 1, labelName: "标签1", color: "#F6C600" },
        { labelID: 2, labelName: "标签2", color: "#EF7F00" },
        { labelID: 3, labelName: "标签3", color: "#F29596" }
      ],
      selected: [],
      colorList: [
        "#F6C600",
        "#EF7F00",
        "#F29596",
        "#EC453C",
        "#8A43E1",
        "#87CB4C",
        "#43A79E",
        "#73B8EE",
        "#3C80E8",
        "#21317B"
      ]
    };
  },
  computed: {},

  created() { },
  mounted() {
    this.initLab(this.labList);
  },
  methods: {
    initLab(val) {
      this.selected = val ? val : [];
    },
    addLabel() {
      if (this.labelName) {
        let data = {
          labelName: this.labelName,
          labelID: Date.parse(new Date()).toString(),
          color: this.color
        };
        // 先显示标签
        this.selected.push(data);
        this.tags.push(data);
      }
      // ---- 这里请求接口添加标签 ----
    },
    // 返回选中的值
    confirm() {
      // this.$emit("select", this.selected);
    },
    // 关闭标签
    closeLabel(index) {
      this.selected = this.selected.filter((item, newIdx) => {
        return newIdx != index;
      });
      this.confirm();
    },
    // 选中标签
    selectLabel(tag) {
      let isRepeat = false;
      this.selected.map(item => {
        if (tag.labelID == item.labelID) {
          isRepeat = true;
          return;
        }
      });
      if (!isRepeat && this.selected && this.selected.length < 6) {
        this.selected = this.selected.concat([tag]);
        this.confirm();
      }
    }
  }
};
</script>

<style>
.pos-center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.pointer {
  cursor: pointer;
}

.el-tag--dark {
  border-color: #fff;
}

.select-tag {
  margin-top: 5px;
  margin-bottom: 5px;
}

.color-item {
  width: 40px;
  height: 30px;
  border-radius: 5px;
  float: left;
  margin: 5px;
  position: relative;
  color: #fff;
}
</style>