Skip to content
This repository was archived by the owner on Dec 6, 2021. It is now read-only.

Commit 0248c52

Browse files
committed
feat(input): add v-model support
1 parent 4a453f4 commit 0248c52

File tree

3 files changed

+54
-45
lines changed

3 files changed

+54
-45
lines changed

src/components/input/index.ts

+27-25
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import {
1010
InputEventDetail,
1111
KeyboardHeightEventDetail,
1212
} from "types/input"
13-
import { ENV_TYPE, getEnv } from "@tarojs/taro"
1413
import { uuid } from "../../utils/common"
14+
import { useModelValue } from "../../composables/model"
1515

1616
type PickAtInputProps = Pick<AtInputProps, 'maxLength' | 'disabled' | 'password'>
1717
type GetInputPropsReturn = PickAtInputProps & Pick<InputProps, 'type'>
@@ -115,15 +115,11 @@ const AtInput = defineComponent({
115115
},
116116
confirmType: {
117117
type: String as () => AtInputProps["confirmType"],
118-
default: 'done' as AtInputProps["confirmType"],
118+
default: 'done',
119119
validator: (val: string) => ["done", "send", "search", "next", "go"].includes(val)
120120
},
121121
// events
122-
onChange: {
123-
type: Function as PropType<AtInputProps['onChange']>,
124-
default: () => () => { },
125-
required: true
126-
},
122+
onChange: Function as PropType<AtInputProps['onChange']>,
127123
onBlur: Function as PropType<AtInputProps['onBlur']>,
128124
onFocus: Function as PropType<AtInputProps['onFocus']>,
129125
onConfirm: Function as PropType<AtInputProps['onConfirm']>,
@@ -132,11 +128,9 @@ const AtInput = defineComponent({
132128
onErrorClick: Function as PropType<AtInputProps['onErrorClick']>
133129
},
134130

135-
setup(props: AtInputProps, { attrs, slots }) {
136-
const inputValue = ref(props.value)
131+
setup(props: AtInputProps, { attrs, slots, emit }) {
132+
const inputValue = useModelValue(props, emit, 'value')
137133
const inputID = ref('weui-input' + uuid())
138-
const isWEB = ref(getEnv() === ENV_TYPE.WEB)
139-
140134
const inputProps = computed(() => getInputProps(props))
141135

142136
const rootClasses = computed(() => ({
@@ -162,23 +156,27 @@ const AtInput = defineComponent({
162156
'at-input__title--required': props.required
163157
}))
164158

165-
watch(() => props.value, (val, preVal) => {
166-
if (val !== preVal) {
167-
inputValue.value = val
168-
}
169-
})
159+
// watch(() => props.value, (val, preVal) => {
160+
// if (val !== preVal) {
161+
// inputValue.value = val
162+
// }
163+
// })
170164

171165
function handleInput(e: BaseEventOrig<InputEventDetail>) {
172-
props.onChange(e.detail.value, e)
166+
if (attrs['onUpdate:value']) {
167+
inputValue.value = e.detail.value
168+
} else {
169+
props.onChange?.(e.detail.value, e)
170+
}
173171
}
174172

175173
function handleFocus(e: BaseEventOrig<FocusEventDetail>) {
176174
if (typeof props.onFocus === 'function') {
177175
props.onFocus(e.detail.value, e)
178176
}
179-
if (isWEB.value) {
177+
if (process.env.TARO_ENV === 'h5') {
180178
// hack fix: h5 点击清除按钮后,input value 在数据层被清除,但视图层仍未清除
181-
inputID.value = 'weui-input' + String(e.timeStamp).replace('.', '')
179+
inputID.value = 'weui-input' + uuid(10, 32)
182180
}
183181
}
184182

@@ -201,14 +199,17 @@ const AtInput = defineComponent({
201199
}
202200

203201
function handleClearValue(e: ITouchEvent) {
204-
props.onChange('', e)
202+
if (attrs['onUpdate:value']) {
203+
inputValue.value = ''
204+
} else {
205+
props.onChange?.('', e)
206+
}
205207

206208
// hack fix: h5 点击清除按钮后,input value 在数据层被清除,但视图层仍未清除
207-
if (isWEB.value) {
209+
if (process.env.TARO_ENV === 'h5') {
208210
const inputNode = document.querySelector<HTMLInputElement>(`#${inputID.value} > .weui-input`)
209211
inputNode!.value = ''
210212
}
211-
212213
}
213214

214215
function handleKeyboardHeightChange(
@@ -247,8 +248,9 @@ const AtInput = defineComponent({
247248
}, { default: () => props.title })
248249
),
249250

250-
h(Input, mergeProps(isWEB.value ? { id: inputID.value } : {}, {
251+
h(Input, {
251252
class: 'at-input__input',
253+
id: inputID.value,
252254
name: props.name,
253255
type: inputProps.value.type,
254256
password: inputProps.value.password,
@@ -270,7 +272,7 @@ const AtInput = defineComponent({
270272
onFocus: handleFocus,
271273
onConfirm: handleConfirm,
272274
onKeyboardHeightChange: handleKeyboardHeightChange,
273-
})),
275+
}),
274276

275277
(props.clear && props.value) && (
276278
h(View, {
@@ -300,7 +302,7 @@ const AtInput = defineComponent({
300302

301303
h(View, {
302304
class: 'at-input__children'
303-
}, { default: () => slots.default && slots.default() })
305+
}, { default: () => slots.default?.() })
304306
]
305307
})
306308
]

src/pages/form/input/index.vue

+25-18
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,15 @@
1111
name="value1"
1212
title="标准五个字"
1313
type="text"
14-
placeholder="标准五个字"
15-
:value="value1"
16-
@change="handleInput('value1', $event)"
14+
placeholder="使用了 v-model:value 更新 value"
15+
v-model:value="value1"
1716
/>
1817
<at-input
1918
name="value2"
2019
title="标题实在特别长就换行"
21-
placeholder="其他列保持正常间距"
22-
:value="value2"
23-
@change="handleInput('value2', $event)"
20+
placeholder="使用了 onChange 更新 value"
21+
:value="value1"
22+
@change="handleInput('value1', $event)"
2423
/>
2524
<at-input
2625
name="value3"
@@ -137,8 +136,7 @@
137136
title="清除按钮"
138137
type="text"
139138
placeholder="点击清除按钮清空内容"
140-
:value="value13"
141-
@change="handleInput('value13', $event)"
139+
v-model:value="value13"
142140
/>
143141
<at-input
144142
clear
@@ -148,8 +146,7 @@
148146
title="必填项"
149147
type="text"
150148
placeholder="必须填写内容"
151-
:value="value16"
152-
@change="handleInput('value16', $event)"
149+
v-model:value="value16"
153150
/>
154151
<at-input
155152
clear
@@ -158,8 +155,7 @@
158155
title="监听事件"
159156
type="text"
160157
placeholder="监听键盘高度事件"
161-
:value="value17"
162-
@change="handleInput('value17', $event)"
158+
v-model:value="value17"
163159
@keyboard-height-change="handleKeyboardHeightChange"
164160
/>
165161
</at-form>
@@ -181,19 +177,20 @@
181177
type="text"
182178
placeholder="验证码"
183179
:maxLength="4"
184-
:value="value14"
185-
@change="handleInput('value14', $event)"
180+
v-model:value="value14"
186181
>
187-
<image :src="verificationCode" />
182+
<image
183+
:src="verificationCode"
184+
:style="imageStyle"
185+
/>
188186
</at-input>
189187
<at-input
190188
clear
191189
name="value15"
192190
type="phone"
193191
placeholder="请输入手机号码"
194192
:border="false"
195-
:value="value15"
196-
@change="handleInput('value15', $event)"
193+
v-model:value="value15"
197194
>
198195
<view
199196
:style="{
@@ -212,7 +209,7 @@
212209
</template>
213210

214211
<script lang="ts">
215-
import { defineComponent, reactive, toRefs } from 'vue'
212+
import { computed, defineComponent, reactive, toRefs } from 'vue'
216213
import Taro from '@tarojs/taro'
217214
218215
import { AtForm, AtInput } from '../../../index'
@@ -252,6 +249,15 @@ export default defineComponent({
252249
second: 60,
253250
})
254251
252+
const imageStyle = computed(() => {
253+
if (process.env.TARO_ENV === 'h5') {
254+
return {
255+
width: 'unset',
256+
height: 'unset',
257+
}
258+
}
259+
})
260+
255261
function showTipText() {
256262
return state.disabled ? `${state.second}s后重试` : '发送验证码'
257263
}
@@ -303,6 +309,7 @@ export default defineComponent({
303309
304310
return {
305311
...toRefs(state),
312+
imageStyle,
306313
verificationCode,
307314
handleInput,
308315
showTipText,

types/input.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,10 @@ export interface AtInputProps extends AtComponent, OmitInputProps {
133133
*/
134134
onFocus?: InputFunction<string | number, FocusEventDetail>
135135
/**
136-
* 输入框值改变时触发的事件,开发者需要通过 onChange 事件来更新 value 值变化,onChange 函数必填
136+
* 输入框值改变时触发的事件,开发者可通过 onChange 事件或 v-model:value 来更新 value 值变化,使用 v-model 时,无需 onChange 函数
137137
* 小程序中,如果想改变 value 的值,需要 return value 从而改变输入框的当前值, v2.0.3 版本可以获取 event 参数
138138
*/
139-
onChange: InputFunction<string | number, InputEventDetail, any>
139+
onChange?: InputFunction<string | number, InputEventDetail, any>
140140
/**
141141
* 点击完成按钮时触发,v2.0.3 版本可以获取 event 参数
142142
*/

0 commit comments

Comments
 (0)