<template>
<a-textarea
:placeholder="placeholder"
:cols="cols"
:rows="rows"
:auto-size="autoSize"
v-model="showText"
@change="textareaChange"
:allow-clear="allowClear"
@keydown="keydown"
/>
</template>
<script>
export default {
name: "GbTextarea",
props: {
change: {
type: Function
},
modelValue: {
type: [String, Number],
default: ""
},
rowLen: {
type: Number,
default: 10
},
autoSize: {
type: [Boolean, Object]
},
rows: {
type: Number,
default: 3
},
cols: {
type: Number,
default: 30
},
placeholder: {
type: String,
default: ""
},
maxLength: {
type: Number,
default: 30
},
allowClear: {
type: Boolean,
default: false
}
},
data () {
return {
showText: "",
deleteCode: false
}
},
watch: {
modelValue: {
handler (newVal) {
this.setShowText(`${newVal}`)
},
immediate: true
}
},
methods: {
// 设置值的操作
setShowText (numberValueStr) {
let len = 0
let originalLen = 0
const _val = []
const val = numberValueStr.replaceAll("\n", "")
for (let i = 0; i < val.length; i++) { // 循环值通过条件换行
if (len < this.maxLength) {
originalLen++
if (val.charCodeAt(i) > 127 || val.charCodeAt(i) === 94) {
len += 2
} else {
len++
}
_val.push(val[i])
// 如果行内有半角和全角混合,就会出现不换行,这里处理这种情况发生
if ((len + 1) % this.rowLen === 0 && originalLen !== len) {
if (val.charCodeAt(i + 1) > 127 || val.charCodeAt(i + 1) === 94) {
len++
}
}
if (len % this.rowLen === 0 && len < this.maxLength) {
if (this.deleteCode && i === val.length - 1) {
console.log("a")
} else {
_val.push("\n")
}
}
}
}
this.showText = _val.join("")
this.$emit("update:modelValue", this.showText)
},
textareaChange (e) {
const val = e.currentTarget.value
this.setShowText(val)
this.$emit("change")
},
keydown (e) { // 记录当前键盘事件
if (e.code === "Backspace" || e.code === "Delete") {
this.deleteCode = true
} else {
this.deleteCode = false
}
// 记录光标位置,以防赋值时光标跑到后面去,该写法有点问题,目前只支持半角字符
if (e.code !== "ArrowLeft" && e.code !== "ArrowReft" && e.code !== "ArrowDown" && e.code !== "ArrowUp") {
const start = e.target.selectionStart
const end = e.target.selectionEnd
const target = e.target
setTimeout(function () {
target.focus()
target.selectionStart = start + 1
target.selectionEnd = end + 1
})
}
}
}
}
</script>
方法:利用css
.receipt{
@font-size: 26px;
:deep(.ant-form-item-control) {
text-align: center;
}
textarea {
font-size: @font-size;
resize: none !important;
font-family: monospace, "my-monospace";
width: 20.4em;
letter-spacing: 0;
word-break: break-all;
overflow: hidden;
box-sizing: content-box;
// 关闭字体提升,防止字体跟随分辨率变化
text-size-adjust: none;
-webkit-text-size-adjust:none;
transform: scale(0.7);
transform-origin: center center;
}
}