提交 4c30e74d 编写于 作者: Q qiang

fix: 修复部分时机获取 input、textarea 组件值不正确的问题 question/115897

上级 c75eaf24
<template>
<uni-input
@change.stop
v-on="$listeners"
>
<uni-input v-on="$listeners">
<div
ref="wrapper"
class="uni-input-wrapper"
......@@ -20,6 +17,7 @@
ref="input"
v-model="valueSync"
v-keyboard
v-field
:disabled="disabled"
:type="inputType"
:maxlength="maxlength"
......@@ -27,11 +25,12 @@
:enterkeyhint="confirmType"
class="uni-input-input"
autocomplete="off"
@change.stop
@focus="_onFocus"
@blur="_onBlur"
@input.stop="_onInput"
@compositionstart="_onComposition"
@compositionend="_onComposition"
@compositionstart.stop="_onComposition"
@compositionend.stop="_onComposition"
@keyup.enter.stop="_onKeyup"
>
<!-- fix: 禁止 readonly 状态获取焦点 -->
......@@ -45,7 +44,7 @@
:maxlength="maxlength"
:step="step"
class="uni-input-input"
@focus="$event=>$event.target.blur()"
@focus="($event) => $event.target.blur()"
>
</div>
</uni-input>
......@@ -164,8 +163,6 @@ export default {
}
$vm = $vm.$parent
}
this._initField('input')
},
beforeDestroy () {
this.$dispatch('Form', 'uni-form-group-update', {
......@@ -179,7 +176,7 @@ export default {
value: $event.target.value
})
},
_onInput ($event) {
_onInput ($event, force) {
if (this.composing) {
return
}
......@@ -213,7 +210,7 @@ export default {
}
this.$triggerInput($event, {
value: this.valueSync
})
}, force)
},
_onFocus ($event) {
this.$trigger('focus', $event, {
......@@ -221,6 +218,11 @@ export default {
})
},
_onBlur ($event) {
// iOS 输入法 compositionend 事件可能晚于 blur
if (this.composing) {
this.composing = false
this._onInput($event, true)
}
this.$trigger('blur', $event, {
value: $event.target.value
})
......@@ -228,7 +230,7 @@ export default {
_onComposition ($event) {
if ($event.type === 'compositionstart') {
this.composing = true
} else {
} else if (this.composing) {
this.composing = false
// 部分输入法 compositionend 事件可能晚于 input
this._onInput($event)
......
<template>
<uni-textarea
@change.stop
v-on="$listeners"
>
<uni-textarea v-on="$listeners">
<div class="uni-textarea-wrapper">
<div
v-show="!(composition || valueSync.length)"
v-show="!(composing || valueSync.length)"
ref="placeholder"
:style="placeholderStyle"
:class="placeholderClass"
......@@ -33,14 +30,16 @@
ref="textarea"
v-model="valueSync"
v-keyboard
v-field
:disabled="disabled"
:maxlength="maxlengthNumber"
:class="{ 'uni-textarea-textarea-fix-margin': fixMargin }"
:style="{ 'overflow-y': autoHeight ? 'hidden' : 'auto' }"
:enterkeyhint="confirmType"
class="uni-textarea-textarea"
@compositionstart="_onCompositionstart"
@compositionend="_onCompositionend"
@change.stop
@compositionstart.stop="_onCompositionstart"
@compositionend.stop="_onCompositionend"
@input.stop="_onInput"
@focus="_onFocus"
@blur="_onBlur"
......@@ -59,7 +58,7 @@
:class="{ 'uni-textarea-textarea-fix-margin': fixMargin }"
:style="{ 'overflow-y': autoHeight ? 'hidden' : 'auto' }"
class="uni-textarea-textarea"
@focus="$event=>$event.target.blur()"
@focus="($event) => $event.target.blur()"
/>
</div>
</uni-textarea>
......@@ -121,7 +120,7 @@ export default {
data () {
return {
valueComposition: '',
composition: false,
composing: false,
focusSync: this.focus,
height: 0,
focusChangeSource: '',
......@@ -149,7 +148,7 @@ export default {
return isNaN(selectionEnd) ? -1 : selectionEnd
},
valueCompute () {
return (this.composition ? this.valueComposition : this.valueSync).split('\n')
return (this.composing ? this.valueComposition : this.valueSync).split('\n')
},
isDone () {
return ['done', 'go', 'next', 'search', 'send'].includes(this.confirmType)
......@@ -210,8 +209,6 @@ export default {
}
$vm = $vm.$parent
}
this._initField('textarea')
},
beforeDestroy () {
this.$dispatch('Form', 'uni-form-group-update', {
......@@ -249,6 +246,11 @@ export default {
}
},
_onBlur: function ($event) {
// iOS 输入法 compositionend 事件可能晚于 blur
if (this.composing) {
this.composing = false
this._onInput($event, true)
}
this.focusSync = false
this.$trigger('blur', $event, {
value: this.valueSync,
......@@ -256,12 +258,14 @@ export default {
})
},
_onCompositionstart ($event) {
this.composition = true
this.composing = true
},
_onCompositionend ($event) {
this.composition = false
// 部分输入法 compositionend 事件可能晚于 input
this._onInput($event)
if (this.composing) {
this.composing = false
// 部分输入法 compositionend 事件可能晚于 input
this._onInput($event)
}
},
// 暂无完成按钮,此功能未实现
_confirm ($event) {
......@@ -280,15 +284,15 @@ export default {
_resize ({ height }) {
this.height = height
},
_onInput ($event) {
if (this.composition) {
_onInput ($event, force) {
if (this.composing) {
this.valueComposition = $event.target.value
return
}
this.$triggerInput($event, {
value: this.valueSync,
cursor: this.$refs.textarea.selectionEnd
})
}, force)
},
_getFormData () {
return {
......
......@@ -79,21 +79,31 @@ export default {
this.$emit('update:value', detail.value)
this.$trigger('input', $event, detail)
}, 100)
this.$triggerInput = ($event, detail) => {
this.$triggerInput = ($event, detail, force) => {
this.__valueChange.cancel()
this.__triggerInput($event, detail)
if (force) {
this.__triggerInput.flush()
}
}
},
beforeDestroy () {
this.__valueChange.cancel()
this.__triggerInput.cancel()
},
directives: {
field: {
inserted (el, binding, vnode) {
vnode.context._initField(el)
}
}
},
methods: {
_getValueString (value) {
return value === null ? '' : String(value)
},
_initField (ref) {
this._fieldRef = ref
_initField (el) {
this._field = el
startTime = startTime || Date.now()
if (this.needFocus) {
this._focus()
......@@ -103,7 +113,7 @@ export default {
if (!this.needFocus) {
return
}
const field = this.$refs[this._fieldRef]
const field = this._field
if (!field || (__PLATFORM__ === 'app-plus' && !window.plus)) {
setTimeout(this._focus.bind(this), 100)
return
......@@ -121,7 +131,7 @@ export default {
}
},
_blur () {
const field = this.$refs[this._fieldRef]
const field = this._field
field && field.blur()
}
}
......
......@@ -49,13 +49,13 @@ const camelizeRE = /-(\w)/g
export const camelize = cached((str) => {
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})
/**
* Capitalize a string.
*/
export const capitalize = cached((str) => {
return str.charAt(0).toUpperCase() + str.slice(1)
})
/**
* Capitalize a string.
*/
export const capitalize = cached((str) => {
return str.charAt(0).toUpperCase() + str.slice(1)
})
export function setProperties (item, props, propsData) {
props.forEach(function (name) {
......@@ -107,10 +107,12 @@ export function debounce (fn, delay) {
export function throttle (fn, wait) {
let last = 0
let timeout
let waitCallback
const newFn = function (...arg) {
const now = Date.now()
clearTimeout(timeout)
const waitCallback = () => {
waitCallback = () => {
waitCallback = null
last = now
fn.apply(this, arg)
}
......@@ -122,6 +124,11 @@ export function throttle (fn, wait) {
}
newFn.cancel = function () {
clearTimeout(timeout)
waitCallback = null
}
newFn.flush = function () {
clearTimeout(timeout)
waitCallback && waitCallback()
}
return newFn
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册