index.vue 4.07 KB
<template>
  <div class="eagle-input-tag">
    <el-tag :key="index" v-for="(tag, index) in model" closable disable-transitions @close="handleClose(tag)" size="mini" type="info">
      {{ tag }}
    </el-tag>
    <input v-model="inputValue" @keydown.enter="handleInputConfirm" @keydown.delete="handleDelete" :placeholder="_placeholder" />
    <div class="btn-clear" v-if="clearable && (inputValue || model.length > 0)">
      <i class="el-icon-circle-close" @click="handleClear"></i>
    </div>
  </div>
</template>

<script>
export default {
  name: 'KeywordInput',
  props: {
    value: [Array, String],
    placeholder: String,
    unique: {
      type: Boolean,
      default: true,
    },
    deletable: {
      type: Boolean,
      default: false,
    },
    clearable: {
      type: Boolean,
      default: false,
    },
    type: {
      type: String,
      default: 'array', // array | string
    },
  },
  data: () => ({
    model: [],
    inputValue: '',
  }),
  watch: {
    value: {
      handler(val) {
        if (this.type === 'string') {
          this.model = val
            ? val
                .replace(/,/, ',')
                .replace(/\s+/g, '')
                .split(',')
            : [];
        } else {
          this.model = val || [];
        }
        if (!val || (val && val.length === 0)) {
          this.inputValue = '';
        }
      },
      immediate: true,
    },
  },
  computed: {
    _placeholder() {
      if (!this.value || (this.value && this.value.length === 0)) {
        return this.placeholder || this.i18n('eagle.input.input') || '请输入';
      } else {
        return undefined;
      }
    },
  },
  methods: {
    handleClose(tag) {
      this.model.splice(this.model.indexOf(tag), 1);
      this.emitValue();
    },
    handleInputConfirm() {
      let inputValue = this.inputValue;
      if (inputValue) {
        if (this.unique) {
          let modelSet = new Set([...this.model]);
          modelSet.add(inputValue);
          this.model = Array.from(modelSet);
        } else {
          this.model.push(inputValue);
        }
      }
      this.inputValue = '';
      this.emitValue();
    },
    emitValue() {
      if (this.type === 'string') {
        this.$emit('input', this.model.join(','));
      } else {
        this.$emit('input', this.model);
      }
    },
    handleDelete() {
      if (!this.inputValue && this.model && this.model.length > 0 && this.deletable) {
        this.model.splice(this.model.length - 1, 1);
        this.emitValue();
      }
    },
    handleClear() {
      this.inputValue = '';
      this.model = [];
      this.emitValue();
    },
  },
};
</script>

<style>
.eagle-input-tag {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  -webkit-appearance: none;
  background-color: #ffffff;
  background-image: none;
  border-radius: 4px;
  border: 1px solid #dcdfe6;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  color: #606266;
  font-size: inherit;
  outline: none;
  padding: 5px 5px 0px 5px;
  -webkit-transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
  transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
  width: 100%;
}
.eagle-input-tag:hover {
  border-color: #c0c4cc;
}
.eagle-input-tag .el-tag:not(:last-child) {
  margin-right: 5px;
  margin-bottom: 5px;
}
.eagle-input-tag input {
  flex: auto;
  -webkit-appearance: none;
  background-color: #ffffff;
  background-image: none;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  color: #606266;
  display: inline-block;
  font-size: inherit;
  outline: none;
  padding: 0 5px;
  margin-bottom: 5px;
  -webkit-transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
  transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
  border: 0;
  font-size: 14px;

  height: 20px;
  padding: 0 5px;
  line-height: 19px;
}
.eagle-input-tag .btn-clear {
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.eagle-input-tag .btn-clear i {
  cursor: pointer;
  position: relative;
  top: -2px;
  color: #dcdfe6;
}
.eagle-input-tag .btn-clear i:hover {
  color: #606266;
}
</style>