uni-app textarea字数限制不准确
uni-app textarea字数限制不准确
操作步骤:
- 正常操作
预期结果:
- 没有bug
实际结果:
- 有bug
bug描述:
- textarea上的字数限制属性设置的是140字,我复制了超过140字的文章粘贴到textarea上只有138个字,使用@input方法监听字数是140个字,这个问题一直都存在,之前也提过这个问题,一直没有解决,看附件
附件:
信息类别 | 详细信息 |
---|---|
产品分类 | uniapp/App |
PC开发环境操作系统 | Windows |
PC开发环境操作系统版本号 | 11 |
HBuilderX类型 | Alpha |
HBuilderX版本号 | 3.8.12 |
手机系统 | iOS |
手机系统版本号 | iOS 15 |
手机厂商 | 苹果 |
手机机型 | 苹果11 |
页面类型 | vue |
vue版本 | vue2 |
打包方式 | 云端 |
项目创建方式 | HBuilderX |
我自测纯文字 150 字复制粘贴未能复现。你提供下视频的文本吧
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
<view>一二三四五六七八九十二二三四五六七八九十三二三四五六七八九十四二三四五六七八九十五二三四五六七八九十六二三四五六七八九十七二三四五六七八九十八二三四五六七八九十九二三四五六七八九十百二三四五六七八九十一二三四五六七八九十二二三四五六七八九十三二三四五六七八九十四二三四五六七八九十前面是一百四十个字</view>
<textarea v-model="str" placeholder="input text..." :maxlength="140"></textarea>
</view>
</view>
</template>
怎么解决呢
怎么解决
1
111
11111
1111
在 uni-app
中使用 textarea
组件时,可能会遇到字数限制不准确的问题。这通常是由于 textarea
的 maxlength
属性与实际的字符计数方式不一致导致的。以下是一些可能的原因和解决方案:
1. maxlength
属性的限制
textarea
组件的 maxlength
属性是基于字符数进行限制的,而不是字节数。如果你需要限制字节数(例如在 UTF-8 编码中,某些字符可能占用多个字节),maxlength
可能无法满足你的需求。
解决方案:
你可以通过监听 textarea
的 input
事件,手动计算输入的字节数,并在达到限制时阻止进一步输入。
<template>
<view>
<textarea :value="inputValue" @input="handleInput" placeholder="请输入内容"></textarea>
<view>已输入字节数:{{ byteCount }} / {{ maxByteLength }}</view>
</view>
</template>
<script>
export default {
data() {
return {
inputValue: '',
maxByteLength: 100, // 最大字节数
byteCount: 0,
};
},
methods: {
handleInput(event) {
const value = event.detail.value;
const byteCount = this.getByteLength(value);
if (byteCount <= this.maxByteLength) {
this.inputValue = value;
this.byteCount = byteCount;
} else {
// 如果超过最大字节数,截取字符串
const truncatedValue = this.truncateString(value, this.maxByteLength);
this.inputValue = truncatedValue;
this.byteCount = this.getByteLength(truncatedValue);
}
},
getByteLength(str) {
// 计算字符串的字节数
return new Blob([str]).size;
},
truncateString(str, maxByteLength) {
// 截取字符串,确保不超过最大字节数
let result = '';
let byteCount = 0;
for (let i = 0; i < str.length; i++) {
const char = str[i];
const charByteLength = this.getByteLength(char);
if (byteCount + charByteLength > maxByteLength) {
break;
}
result += char;
byteCount += charByteLength;
}
return result;
},
},
};
</script>
2. textarea
的 maxlength
属性与 v-model
的冲突
如果你使用 v-model
绑定 textarea
的值,并且同时设置了 maxlength
,可能会出现字数限制不准确的情况。这是因为 v-model
会在 input
事件触发后更新数据,而 maxlength
是在 input
事件之前进行限制的。
解决方案:
你可以使用 @input
事件手动处理输入,并在达到限制时阻止进一步输入。
<template>
<view>
<textarea :value="inputValue" @input="handleInput" :maxlength="maxLength" placeholder="请输入内容"></textarea>
<view>已输入字符数:{{ inputValue.length }} / {{ maxLength }}</view>
</view>
</template>
<script>
export default {
data() {
return {
inputValue: '',
maxLength: 100, // 最大字符数
};
},
methods: {
handleInput(event) {
const value = event.detail.value;
if (value.length <= this.maxLength) {
this.inputValue = value;
} else {
// 如果超过最大字符数,截取字符串
this.inputValue = value.slice(0, this.maxLength);
}
},
},
};
</script>
3. 多字节字符的处理
某些字符(如中文、日文、韩文等)在 UTF-8 编码中可能占用多个字节。如果你需要限制字节数,而不是字符数,maxlength
属性可能无法满足你的需求。
解决方案:
你可以使用 Blob
对象来计算字符串的字节数,并在达到限制时阻止进一步输入。
<template>
<view>
<textarea :value="inputValue" @input="handleInput" placeholder="请输入内容"></textarea>
<view>已输入字节数:{{ byteCount }} / {{ maxByteLength }}</view>
</view>
</template>
<script>
export default {
data() {
return {
inputValue: '',
maxByteLength: 100, // 最大字节数
byteCount: 0,
};
},
methods: {
handleInput(event) {
const value = event.detail.value;
const byteCount = this.getByteLength(value);
if (byteCount <= this.maxByteLength) {
this.inputValue = value;
this.byteCount = byteCount;
} else {
// 如果超过最大字节数,截取字符串
const truncatedValue = this.truncateString(value, this.maxByteLength);
this.inputValue = truncatedValue;
this.byteCount = this.getByteLength(truncatedValue);
}
},
getByteLength(str) {
// 计算字符串的字节数
return new Blob([str]).size;
},
truncateString(str, maxByteLength) {
// 截取字符串,确保不超过最大字节数
let result = '';
let byteCount = 0;
for (let i = 0; i < str.length; i++) {
const char = str[i];
const charByteLength = this.getByteLength(char);
if (byteCount + charByteLength > maxByteLength) {
break;
}
result += char;
byteCount += charByteLength;
}
return result;
},
},
};
</script>