fix(Field): fix the length of emoji (#10033)

This commit is contained in:
neverland 2021-12-12 20:29:10 +08:00 committed by GitHub
parent d5fdab55cc
commit b893f911a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 20 deletions

View File

@ -27,12 +27,14 @@ import {
createNamespace,
} from '../utils';
import {
cutString,
runSyncRule,
endComposing,
mapInputType,
startComposing,
getRuleMessage,
resizeTextarea,
getStringLength,
runRuleValidator,
} from './utils';
import { cellSharedProps } from '../cell/Cell';
@ -255,12 +257,12 @@ export default defineComponent({
// see: https://github.com/youzan/vant/issues/5033
const limitValueLength = (value: string) => {
const { maxlength } = props;
if (isDef(maxlength) && value.length > maxlength) {
if (isDef(maxlength) && getStringLength(value) > maxlength) {
const modelValue = getModelValue();
if (modelValue && modelValue.length === +maxlength) {
if (modelValue && getStringLength(modelValue) === +maxlength) {
return modelValue;
}
return value.slice(0, +maxlength);
return cutString(value, +maxlength);
}
return value;
};
@ -462,7 +464,7 @@ export default defineComponent({
const renderWordLimit = () => {
if (props.showWordLimit && props.maxlength) {
const count = getModelValue().length;
const count = getStringLength(getModelValue());
return (
<div class={bem('word-limit')}>
<span class={bem('word-num')}>{count}</span>/{props.maxlength}

View File

@ -62,21 +62,11 @@ exports[`should render textarea when type is textarea 1`] = `
`;
exports[`should render word limit correctly 1`] = `
<div class="van-cell van-field">
<div class="van-cell__value van-cell__value--alone van-field__value">
<div class="van-field__body">
<input type="text"
id="van-field-input"
class="van-field__control"
>
</div>
<div class="van-field__word-limit">
<span class="van-field__word-num">
3
</span>
/3
</div>
</div>
<div class="van-field__word-limit">
<span class="van-field__word-num">
3
</span>
/3
</div>
`;
@ -117,3 +107,12 @@ exports[`should render word limit correctly when modelValue is undefined 1`] = `
</div>
</div>
`;
exports[`should render word limit with emoji correctly 1`] = `
<div class="van-field__word-limit">
<span class="van-field__word-num">
2
</span>
/3
</div>
`;

View File

@ -343,7 +343,7 @@ test('should render word limit correctly', () => {
showWordLimit: true,
},
});
expect(wrapper.html()).toMatchSnapshot();
expect(wrapper.find('.van-field__word-limit').html()).toMatchSnapshot();
});
test('should render word limit correctly when modelValue is undefined', () => {
@ -475,3 +475,26 @@ test('should render error-message slot correctly', async () => {
expect(wrapper.find('.van-field__error-message').html()).toMatchSnapshot();
});
test('should limit maxlength with emoji correctly', async () => {
const wrapper = mount(Field, {
props: {
maxlength: 3,
modelValue: '😀😀😀😀',
},
});
const input = wrapper.find('input');
expect(input.element.value).toEqual('😀😀😀');
});
test('should render word limit with emoji correctly', () => {
const wrapper = mount(Field, {
props: {
modelValue: '😀😀',
maxlength: 3,
showWordLimit: true,
},
});
expect(wrapper.find('.van-field__word-limit').html()).toMatchSnapshot();
});

View File

@ -107,3 +107,14 @@ export function mapInputType(type: FieldType): {
return { type };
}
// get correct length of emoji
// https://github.com/youzan/vant/issues/10032
export function getStringLength(str: string) {
return [...str].length;
}
// cut string with emoji
export function cutString(str: string, maxlength: number) {
return [...str].slice(0, maxlength).join('');
}