index.vue
2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<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>