mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-09-02 14:19:46 +08:00
feat: migrate Field component
This commit is contained in:
parent
6f6aaeea87
commit
75421a4727
@ -8,6 +8,7 @@
|
|||||||
- Popup: `v-model` 重命名为 `v-model:show`
|
- Popup: `v-model` 重命名为 `v-model:show`
|
||||||
- ShareSheet: `v-model` 重命名为 `v-model:show`
|
- ShareSheet: `v-model` 重命名为 `v-model:show`
|
||||||
- ActionSheet: `v-model` 重命名为 `v-model:show`
|
- ActionSheet: `v-model` 重命名为 `v-model:show`
|
||||||
|
- Field: v-model 对应的属性 `value` 重命名为 `modelValue`,事件由 `input` 重命名为 `update:modelValue`
|
||||||
- Switch: v-model 对应的属性 `value` 重命名为 `modelValue`,事件由 `input` 重命名为 `update:modelValue`
|
- Switch: v-model 对应的属性 `value` 重命名为 `modelValue`,事件由 `input` 重命名为 `update:modelValue`
|
||||||
- Sidebar: v-model 对应的属性 `activeKey` 重命名为 `modelValue`,事件由 `input` 重命名为 `update:modelValue`
|
- Sidebar: v-model 对应的属性 `activeKey` 重命名为 `modelValue`,事件由 `input` 重命名为 `update:modelValue`
|
||||||
- TreeSelect: `active-id.sync` 重命名为 `v-model:active-id`
|
- TreeSelect: `active-id.sync` 重命名为 `v-model:active-id`
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
'button',
|
'button',
|
||||||
'cell',
|
'cell',
|
||||||
|
'cell-group',
|
||||||
'icon',
|
'icon',
|
||||||
'info',
|
'info',
|
||||||
'image',
|
'image',
|
||||||
@ -35,4 +36,5 @@ module.exports = [
|
|||||||
'notice-bar',
|
'notice-bar',
|
||||||
'share-sheet',
|
'share-sheet',
|
||||||
'pull-refresh',
|
'pull-refresh',
|
||||||
|
'field',
|
||||||
];
|
];
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<demo-block :title="t('disabled')">
|
<demo-block :title="t('disabled')">
|
||||||
<van-field :value="t('inputReadonly')" :label="t('text')" readonly />
|
<van-field :model-value="t('inputReadonly')" :label="t('text')" readonly />
|
||||||
<van-field :value="t('inputDisabled')" :label="t('text')" disabled />
|
<van-field :model-value="t('inputDisabled')" :label="t('text')" disabled />
|
||||||
</demo-block>
|
</demo-block>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -53,10 +53,6 @@ export default createComponent({
|
|||||||
errorMessage: String,
|
errorMessage: String,
|
||||||
errorMessageAlign: String,
|
errorMessageAlign: String,
|
||||||
showWordLimit: Boolean,
|
showWordLimit: Boolean,
|
||||||
value: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'text',
|
default: 'text',
|
||||||
@ -69,6 +65,10 @@ export default createComponent({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
clearTrigger: {
|
clearTrigger: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'focus',
|
default: 'focus',
|
||||||
@ -79,6 +79,18 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
emits: [
|
||||||
|
'blur',
|
||||||
|
'focus',
|
||||||
|
'clear',
|
||||||
|
'click',
|
||||||
|
'keypress',
|
||||||
|
'click-input',
|
||||||
|
'click-left-icon',
|
||||||
|
'click-right-icon',
|
||||||
|
'update:modelValue',
|
||||||
|
],
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
focused: false,
|
focused: false,
|
||||||
@ -88,8 +100,8 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
value() {
|
modelValue(val) {
|
||||||
this.updateValue(this.value);
|
this.updateValue(val);
|
||||||
this.resetValidation();
|
this.resetValidation();
|
||||||
this.validateWithTrigger('onChange');
|
this.validateWithTrigger('onChange');
|
||||||
this.$nextTick(this.adjustSize);
|
this.$nextTick(this.adjustSize);
|
||||||
@ -97,7 +109,7 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.updateValue(this.value, this.formatTrigger);
|
this.updateValue(this.modelValue, this.formatTrigger);
|
||||||
this.$nextTick(this.adjustSize);
|
this.$nextTick(this.adjustSize);
|
||||||
|
|
||||||
if (this.vanForm) {
|
if (this.vanForm) {
|
||||||
@ -114,7 +126,7 @@ export default createComponent({
|
|||||||
computed: {
|
computed: {
|
||||||
showClear() {
|
showClear() {
|
||||||
if (this.clearable && !this.readonly) {
|
if (this.clearable && !this.readonly) {
|
||||||
const hasValue = isDef(this.value) && this.value !== '';
|
const hasValue = isDef(this.modelValue) && this.modelValue !== '';
|
||||||
const trigger =
|
const trigger =
|
||||||
this.clearTrigger === 'always' ||
|
this.clearTrigger === 'always' ||
|
||||||
(this.clearTrigger === 'focus' && this.focused);
|
(this.clearTrigger === 'focus' && this.focused);
|
||||||
@ -132,30 +144,18 @@ export default createComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
listeners() {
|
|
||||||
return {
|
|
||||||
...this.$listeners,
|
|
||||||
blur: this.onBlur,
|
|
||||||
focus: this.onFocus,
|
|
||||||
input: this.onInput,
|
|
||||||
click: this.onClickInput,
|
|
||||||
keypress: this.onKeypress,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
labelStyle() {
|
labelStyle() {
|
||||||
const labelWidth = this.getProp('labelWidth');
|
const labelWidth = this.getProp('labelWidth');
|
||||||
|
|
||||||
if (labelWidth) {
|
if (labelWidth) {
|
||||||
return { width: addUnit(labelWidth) };
|
return { width: addUnit(labelWidth) };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
formValue() {
|
formValue() {
|
||||||
if (this.children && (this.$scopedSlots.input || this.$slots.input)) {
|
if (this.children && this.$slots.input) {
|
||||||
return this.children.value;
|
return this.children.modelValue || this.children.value;
|
||||||
}
|
}
|
||||||
return this.value;
|
return this.modelValue;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -311,8 +311,8 @@ export default createComponent({
|
|||||||
input.value = value;
|
input.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value !== this.value) {
|
if (value !== this.modelValue) {
|
||||||
this.$emit('input', value);
|
this.$emit('update:modelValue', value);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentValue = value;
|
this.currentValue = value;
|
||||||
@ -340,7 +340,7 @@ export default createComponent({
|
|||||||
|
|
||||||
onBlur(event) {
|
onBlur(event) {
|
||||||
this.focused = false;
|
this.focused = false;
|
||||||
this.updateValue(this.value, 'onBlur');
|
this.updateValue(this.modelValue, 'onBlur');
|
||||||
this.$emit('blur', event);
|
this.$emit('blur', event);
|
||||||
this.validateWithTrigger('onBlur');
|
this.validateWithTrigger('onBlur');
|
||||||
resetScroll();
|
resetScroll();
|
||||||
@ -364,7 +364,7 @@ export default createComponent({
|
|||||||
|
|
||||||
onClear(event) {
|
onClear(event) {
|
||||||
preventDefault(event);
|
preventDefault(event);
|
||||||
this.$emit('input', '');
|
this.$emit('update:modelValue', '');
|
||||||
this.$emit('clear', event);
|
this.$emit('clear', event);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -412,41 +412,41 @@ export default createComponent({
|
|||||||
|
|
||||||
genInput() {
|
genInput() {
|
||||||
const { type } = this;
|
const { type } = this;
|
||||||
const inputSlot = this.slots('input');
|
|
||||||
const inputAlign = this.getProp('inputAlign');
|
const inputAlign = this.getProp('inputAlign');
|
||||||
|
|
||||||
if (inputSlot) {
|
if (this.$slots.input) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
class={bem('control', [inputAlign, 'custom'])}
|
class={bem('control', [inputAlign, 'custom'])}
|
||||||
onClick={this.onClickInput}
|
onClick={this.onClickInput}
|
||||||
>
|
>
|
||||||
{inputSlot}
|
{this.$slots.input()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const inputProps = {
|
const inputProps = {
|
||||||
|
...this.$attrs,
|
||||||
ref: 'input',
|
ref: 'input',
|
||||||
|
name: this.name,
|
||||||
class: bem('control', inputAlign),
|
class: bem('control', inputAlign),
|
||||||
domProps: {
|
value: this.modelValue,
|
||||||
value: this.value,
|
disabled: this.disabled,
|
||||||
},
|
readonly: this.readonly,
|
||||||
attrs: {
|
placeholder: this.placeholder,
|
||||||
...this.$attrs,
|
onBlur: this.onBlur,
|
||||||
name: this.name,
|
onFocus: this.onFocus,
|
||||||
disabled: this.disabled,
|
onInput: this.onInput,
|
||||||
readonly: this.readonly,
|
onClick: this.onClickInput,
|
||||||
placeholder: this.placeholder,
|
onKeypress: this.onKeypress,
|
||||||
},
|
// TODO
|
||||||
on: this.listeners,
|
|
||||||
// add model directive to skip IME composition
|
// add model directive to skip IME composition
|
||||||
directives: [
|
// directives: [
|
||||||
{
|
// {
|
||||||
name: 'model',
|
// name: 'model',
|
||||||
value: this.value,
|
// value: this.modelValue,
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
};
|
};
|
||||||
|
|
||||||
if (type === 'textarea') {
|
if (type === 'textarea') {
|
||||||
@ -472,12 +472,14 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
genLeftIcon() {
|
genLeftIcon() {
|
||||||
const showLeftIcon = this.slots('left-icon') || this.leftIcon;
|
const leftIconSlot = this.$slots['left-icon'];
|
||||||
|
|
||||||
if (showLeftIcon) {
|
if (this.leftIcon || leftIconSlot) {
|
||||||
return (
|
return (
|
||||||
<div class={bem('left-icon')} onClick={this.onClickLeftIcon}>
|
<div class={bem('left-icon')} onClick={this.onClickLeftIcon}>
|
||||||
{this.slots('left-icon') || (
|
{leftIconSlot ? (
|
||||||
|
leftIconSlot()
|
||||||
|
) : (
|
||||||
<Icon name={this.leftIcon} classPrefix={this.iconPrefix} />
|
<Icon name={this.leftIcon} classPrefix={this.iconPrefix} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -486,13 +488,14 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
genRightIcon() {
|
genRightIcon() {
|
||||||
const { slots } = this;
|
const rightIconSlot = this.$slots['right-icon'];
|
||||||
const showRightIcon = slots('right-icon') || this.rightIcon;
|
|
||||||
|
|
||||||
if (showRightIcon) {
|
if (this.rightIcon || rightIconSlot) {
|
||||||
return (
|
return (
|
||||||
<div class={bem('right-icon')} onClick={this.onClickRightIcon}>
|
<div class={bem('right-icon')} onClick={this.onClickRightIcon}>
|
||||||
{slots('right-icon') || (
|
{rightIconSlot ? (
|
||||||
|
rightIconSlot()
|
||||||
|
) : (
|
||||||
<Icon name={this.rightIcon} classPrefix={this.iconPrefix} />
|
<Icon name={this.rightIcon} classPrefix={this.iconPrefix} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -502,7 +505,7 @@ export default createComponent({
|
|||||||
|
|
||||||
genWordLimit() {
|
genWordLimit() {
|
||||||
if (this.showWordLimit && this.maxlength) {
|
if (this.showWordLimit && this.maxlength) {
|
||||||
const count = (this.value || '').length;
|
const count = (this.modelValue || '').length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={bem('word-limit')}>
|
<div class={bem('word-limit')}>
|
||||||
@ -541,8 +544,8 @@ export default createComponent({
|
|||||||
genLabel() {
|
genLabel() {
|
||||||
const colon = this.getProp('colon') ? ':' : '';
|
const colon = this.getProp('colon') ? ':' : '';
|
||||||
|
|
||||||
if (this.slots('label')) {
|
if (this.$slots.label) {
|
||||||
return [this.slots('label'), colon];
|
return [this.$slots.label(), colon];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.label) {
|
if (this.label) {
|
||||||
@ -552,27 +555,25 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { slots } = this;
|
const slots = this.$slots;
|
||||||
const labelAlign = this.getProp('labelAlign');
|
const labelAlign = this.getProp('labelAlign');
|
||||||
|
|
||||||
const scopedSlots = {
|
|
||||||
icon: this.genLeftIcon,
|
|
||||||
};
|
|
||||||
|
|
||||||
const Label = this.genLabel();
|
|
||||||
if (Label) {
|
|
||||||
scopedSlots.title = () => Label;
|
|
||||||
}
|
|
||||||
|
|
||||||
const extra = this.slots('extra');
|
|
||||||
if (extra) {
|
|
||||||
scopedSlots.extra = () => extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Cell
|
<Cell
|
||||||
icon={this.leftIcon}
|
icon={this.leftIcon}
|
||||||
size={this.size}
|
size={this.size}
|
||||||
|
class={bem({
|
||||||
|
error: this.showError,
|
||||||
|
disabled: this.disabled,
|
||||||
|
[`label-${labelAlign}`]: labelAlign,
|
||||||
|
'min-height': this.type === 'textarea' && !this.autosize,
|
||||||
|
})}
|
||||||
|
// TODO
|
||||||
|
// vSlot={{
|
||||||
|
// icon: this.genLeftIcon,
|
||||||
|
// title: this.genLabel,
|
||||||
|
// extra: slots.extra,
|
||||||
|
// }}
|
||||||
center={this.center}
|
center={this.center}
|
||||||
border={this.border}
|
border={this.border}
|
||||||
isLink={this.isLink}
|
isLink={this.isLink}
|
||||||
@ -581,14 +582,7 @@ export default createComponent({
|
|||||||
titleStyle={this.labelStyle}
|
titleStyle={this.labelStyle}
|
||||||
valueClass={bem('value')}
|
valueClass={bem('value')}
|
||||||
titleClass={[bem('label', labelAlign), this.labelClass]}
|
titleClass={[bem('label', labelAlign), this.labelClass]}
|
||||||
scopedSlots={scopedSlots}
|
|
||||||
arrowDirection={this.arrowDirection}
|
arrowDirection={this.arrowDirection}
|
||||||
class={bem({
|
|
||||||
error: this.showError,
|
|
||||||
disabled: this.disabled,
|
|
||||||
[`label-${labelAlign}`]: labelAlign,
|
|
||||||
'min-height': this.type === 'textarea' && !this.autosize,
|
|
||||||
})}
|
|
||||||
onClick={this.onClick}
|
onClick={this.onClick}
|
||||||
>
|
>
|
||||||
<div class={bem('body')}>
|
<div class={bem('body')}>
|
||||||
@ -601,9 +595,7 @@ export default createComponent({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.genRightIcon()}
|
{this.genRightIcon()}
|
||||||
{slots('button') && (
|
{slots.button && <div class={bem('button')}>{slots.button()}</div>}
|
||||||
<div class={bem('button')}>{slots('button')}</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{this.genWordLimit()}
|
{this.genWordLimit()}
|
||||||
{this.genMessage()}
|
{this.genMessage()}
|
||||||
|
@ -127,10 +127,10 @@ module.exports = {
|
|||||||
// path: 'datetime-picker',
|
// path: 'datetime-picker',
|
||||||
// title: 'DatetimePicker 时间选择',
|
// title: 'DatetimePicker 时间选择',
|
||||||
// },
|
// },
|
||||||
// {
|
{
|
||||||
// path: 'field',
|
path: 'field',
|
||||||
// title: 'Field 输入框',
|
title: 'Field 输入框',
|
||||||
// },
|
},
|
||||||
// {
|
// {
|
||||||
// path: 'form',
|
// path: 'form',
|
||||||
// title: 'Form 表单',
|
// title: 'Form 表单',
|
||||||
@ -461,10 +461,10 @@ module.exports = {
|
|||||||
// path: 'datetime-picker',
|
// path: 'datetime-picker',
|
||||||
// title: 'DatetimePicker',
|
// title: 'DatetimePicker',
|
||||||
// },
|
// },
|
||||||
// {
|
{
|
||||||
// path: 'field',
|
path: 'field',
|
||||||
// title: 'Field',
|
title: 'Field',
|
||||||
// },
|
},
|
||||||
// {
|
// {
|
||||||
// path: 'form',
|
// path: 'form',
|
||||||
// title: 'Form',
|
// title: 'Form',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user