[bugfix] Field: never change value in blur event & handle style difference between iOS and Android

fix #1849
fix #1779
fix #1735
fix #1906
This commit is contained in:
rex 2019-08-29 20:21:52 +08:00 committed by GitHub
parent 2d37c059d9
commit 8dbf034602
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 53 deletions

View File

@ -20,3 +20,12 @@ export function nextTick(fn: Function) {
fn();
}, 1000 / 30);
}
let systemInfo: WechatMiniprogram.GetSystemInfoSuccessCallbackResult = null;
export function getSystemInfoSync() {
if (systemInfo == null) {
systemInfo = wx.getSystemInfoSync();
}
return systemInfo;
}

View File

@ -134,6 +134,33 @@ Page({
</van-cell-group>
```
## 常见问题
### 真机上为什么会出现聚焦时 placeholder 加粗、闪烁的现象?
由于微信小程序的 input 组件和 textarea 组件是原生组件,聚焦时会将原生的输入框覆盖在对应位置上,导致了这个现象的产生。
相关的讨论可以查看[微信开放社区](https://developers.weixin.qq.com/community/search?query=placeholder%20%E9%97%AA%E7%83%81%20%E5%8A%A0%E7%B2%97)
### 真机上 placeholder 为什么会盖过 popup 等其它组件?
由于微信小程序的 input 组件和 textarea 组件是原生组件,遵循原生组件的限制,详情可以查看[原生组件说明](https://developers.weixin.qq.com/miniprogram/dev/component/native-component.html)
### textarea 的 placeholder 在真机上为什么会偏移?
微信小程序的 textarea 组件在 Android 和 iOS 中默认样式不同,在 iOS 中会有默认的 `padding`,且无法置 0。
同时 `placeholder-style``vertical-align``line-height` 等大量css属性都不生效。
这一系列的问题导致了 placeholder 在真机上可能会出现偏移。vant-weapp 已经尽量抹平 textarea 在不同环境下的差异。
微信已经将 `padding` 的问题列为修复中的问题,可以查看[微信开放社区](https://developers.weixin.qq.com/community/develop/issue/96)
### 手写输入法为什么会丢失部分字符 / 手写输入法为什么不会触发 input 事件?
这是微信小程序的 input 组件本身的问题,如果需要兼容手写输入法的场景,可以在 `blur` 事件中取到输入的值。
相关的讨论可以查看[微信开放社区](https://developers.weixin.qq.com/community/search?query=input%20%E6%89%8B%E5%86%99%E8%BE%93%E5%85%A5&page=1&block=1&random=1567079239098)
### Props
| 参数 | 说明 | 类型 | 默认值 |

View File

@ -7,6 +7,11 @@
&--textarea {
min-height: 24px;
line-height: 1.2em;
}
&--textarea&--ios {
margin-top: -4.5px;
}
}
@ -26,6 +31,11 @@
box-sizing: border-box;
resize: none;
&--textarea {
height: 18px;
min-height: 18px;
}
&--error {
color: @red;
}

View File

@ -1,5 +1,6 @@
import { VantComponent } from '../common/component';
import { Weapp } from 'definitions/weapp';
import { getSystemInfoSync } from '../common/utils';
VantComponent({
field: true,
@ -71,73 +72,35 @@ VantComponent({
},
data: {
showClear: false
},
beforeCreate() {
this.focused = false;
focused: false,
system: getSystemInfoSync().system.split(' ').shift().toLowerCase()
},
methods: {
onInput(event: Weapp.Event) {
const { value = '' } = event.detail || {};
this.set({
value,
showClear: this.getShowClear(value)
}, () => {
this.set({ value }, () => {
this.emitChange(value);
});
},
onFocus(event: Weapp.Event) {
const { value = '', height = 0 } = event.detail || {};
this.$emit('focus', { value, height });
this.focused = true;
this.blurFromClear = false;
this.set({
showClear: this.getShowClear()
});
this.set({ focused: true });
this.$emit('focus', event.detail);
},
onBlur(event: Weapp.Event) {
const { value = '', cursor = 0 } = event.detail || {};
this.$emit('blur', { value, cursor });
this.focused = false;
const showClear = this.getShowClear();
if (this.data.value === value) {
this.set({
showClear
});
} else if (!this.blurFromClear) {
// fix: the handwritten keyboard does not trigger input change
this.set({
value,
showClear
}, () => {
this.emitChange(value);
});
}
this.set({ focused: false });
this.$emit('blur', event.detail);
},
onClickIcon() {
this.$emit('click-icon');
},
getShowClear(value?: string): boolean {
value = value === undefined ? this.data.value : value;
return (
this.data.clearable && this.focused && value && !this.data.readonly
);
},
onClear() {
this.blurFromClear = true;
this.set({
value: '',
showClear: this.getShowClear('')
}, () => {
this.set({ value: '' }, () => {
this.emitChange('');
this.$emit('clear', '');
});

View File

@ -14,15 +14,18 @@
>
<slot name="left-icon" slot="icon" />
<slot name="label" slot="title" />
<view class="van-field__body {{ type === 'textarea' ? 'van-field__body--textarea' : '' }}">
<view class="{{ utils.bem('field__body', [type, system]) }}">
<textarea
wx:if="{{ type === 'textarea' }}"
class="input-class {{ utils.bem('field__input', [inputAlign, { disabled, error }]) }}"
class="input-class {{ utils.bem('field__input', [inputAlign, type, { disabled, error }]) }}"
fixed="{{ fixed }}"
focus="{{ focus }}"
value="{{ value }}"
disabled="{{ disabled || readonly }}"
maxlength="{{ maxlength }}"
placeholder="{{ placeholder }}"
placeholder-style="{{ placeholderStyle }}"
placeholder-class="{{ utils.bem('field__placeholder', { error }) }}"
auto-height="{{ autosize }}"
cursor-spacing="{{ cursorSpacing }}"
adjust-position="{{ adjustPosition }}"
@ -34,9 +37,6 @@
bind:focus="onFocus"
bind:confirm="onConfirm"
>
<view wx:if="{{ value == null || value.length === 0 }}" style="{{ placeholderStyle }}" class="{{ utils.bem('field__placeholder', { error }) }}">
{{ placeholder }}
</view>
</textarea>
<input
wx:else
@ -48,7 +48,7 @@
maxlength="{{ maxlength }}"
placeholder="{{ placeholder }}"
placeholder-style="{{ placeholderStyle }}"
placeholder-class="{{ error ? 'van-field__placeholder--error' : 'van-field__placeholder' }}"
placeholder-class="{{ utils.bem('field__placeholder', { error }) }}"
confirm-type="{{ confirmType }}"
confirm-hold="{{ confirmHold }}"
cursor-spacing="{{ cursorSpacing }}"
@ -62,7 +62,7 @@
bind:confirm="onConfirm"
/>
<van-icon
wx:if="{{ showClear }}"
wx:if="{{ clearable && focused && value && !readonly }}"
size="16px"
name="clear"
class="van-field__clear-root van-field__icon-root"