index.vue 2.72 KB
<template>
  <el-popover
    placement="bottom"
    width="320"
    trigger="manual"
    :popper-class="popperClass"
    v-model="isPopoverVisible"
  >
    <!-- 弹出文本域 -->
    <el-input
      ref="popoverInput"
      type="textarea"
      :rows="5"
      v-model="localValue"
      class="textarea-popover"
      resize="none"
      :maxlength="maxlength"
      @blur="handleBlur"
    ></el-input>

    <!-- 主输入框 -->
    <el-input
      slot="reference"
      ref="referenceInput"
      type="textarea"
      :rows="1"
      class="input-shadow"
      v-model="localValue"
      resize="none"
      @focus="handleFocus"
    ></el-input>
  </el-popover>
</template>

<script>
export default {
  name: "PopoverTextarea",
  props: {
    value: {
      type: String,
      default: "",
    },
    maxlength: {
      type: Number,
      default: 13000,
    },
    maxEntries: {
      type: Number,
      default: 1000, // 最大条目数
    },
    popperClass: {
      type: String,
      default: "popover-input-class",
    },
  },
  data() {
    return {
      isPopoverVisible: false, // 控制 popover 显示
      localValue: this.value, // 输入框内容
    };
  },
  watch: {
    value(newVal) {
      this.localValue = newVal;
    },
    localValue(newVal) {
      this.$emit("input", newVal); // 同步父组件数据
    },
  },
  methods: {
    handleFocus() {
      this.isPopoverVisible = true;
      this.$nextTick(() => {
        this.$refs.popoverInput.focus(); // 弹出层输入框获取焦点
        this.$refs.referenceInput.$el.style.display = "none"; // 隐藏主输入框
      });
    },
    handleBlur() {
      this.isPopoverVisible = false;

      // 格式化内容
      this.localValue = this.formatContent(this.localValue);

      this.$nextTick(() => {
        const referenceInput = this.$refs.referenceInput.$el;
        referenceInput.style.display = "block";
        if (this.localValue) {
          referenceInput.classList.add("inputFocus");
        } else {
          referenceInput.classList.remove("inputFocus");
        }
      });

      this.$emit("blur", this.localValue); // 触发父组件的 blur 事件
    },
    formatContent(value) {
      // 格式化输入内容:替换分隔符、去空格、限制条数
      return value
        .replace(/[\n,;;]/g, ",")
        .split(",")
        .map((item) => item.trim())
        .filter((item) => item !== "")
        .slice(0, this.maxEntries)
        .join("\n");
    },
  },
};
</script>

<style scoped lang="scss">
//.input-shadow {
//  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
//}
//
//.textarea-popover {
//  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
//}
//
//.inputFocus {
//  border-color: #409eff;
//  box-shadow: 0 0 5px rgba(64, 158, 255, 0.5);
//}
</style>