[improvement] AddressEdit: jsx (#2503)

This commit is contained in:
neverland 2019-01-12 11:44:10 +08:00 committed by GitHub
parent 4b8bd8e9be
commit 25c00b1023
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 212 additions and 211 deletions

View File

@ -0,0 +1,81 @@
import { use, isAndroid } from '../utils';
import Cell from '../cell';
import Field from '../field';
const [sfc, bem, t] = use('address-edit-detail');
const android = isAndroid();
export default sfc({
props: {
value: String,
error: Boolean,
focused: Boolean,
detailRows: Number,
searchResult: Array,
showSearchResult: Boolean
},
computed: {
searchList() {
if (this.showSearchResult && this.focused) {
return this.searchResult || [];
}
return [];
},
showIcon() {
return this.value && this.focused;
}
},
methods: {
onSelect(express) {
this.$emit('select-search', express);
this.$emit('input', `${express.address || ''} ${express.name || ''}`.trim());
}
},
render(h) {
return (
<Cell class={bem()}>
<Field
autosize
ref="field"
rows={this.detailRows}
clearable={!android}
type="textarea"
maxlength="200"
value={this.value}
error={this.error}
label={t('label')}
placeholder={t('placeholder')}
{...{ on: this.$listeners }}
>
{this.showIcon && android && (
<div
slot="icon"
class={bem('finish')}
onClick={() => {
this.$refs.field.blur();
}}
>
{t('complete')}
</div>
)}
</Field>
{this.searchList.map(express => (
<Cell
key={express.name + express.address}
title={express.name}
label={express.address}
icon="location-o"
clickable
onClick={() => {
this.onSelect(express);
}}
/>
))}
</Cell>
);
}
});

View File

@ -1,81 +0,0 @@
<template>
<cell :class="b()">
<field
v-on="$listeners"
autosize
ref="field"
:rows="detailRows"
:clearable="!isAndroid"
type="textarea"
maxlength="200"
:value="value"
:error="error"
:label="$t('label')"
:placeholder="$t('placeholder')"
>
<div
v-if="showIcon && isAndroid"
v-text="$t('complete')"
slot="icon"
:class="b('finish')"
@click="$refs.field.blur()"
/>
</field>
<cell
v-for="express in searchList"
:key="express.name + express.address"
:title="express.name"
:label="express.address"
icon="location-o"
clickable
@click="onSelect(express)"
/>
</cell>
</template>
<script>
import create from '../utils/create';
import Field from '../field';
import { isAndroid } from '../utils';
export default create({
name: 'address-edit-detail',
components: {
Field
},
props: {
value: String,
error: Boolean,
focused: Boolean,
detailRows: Number,
searchResult: Array,
showSearchResult: Boolean
},
created() {
this.isAndroid = isAndroid();
},
computed: {
searchList() {
if (this.showSearchResult && this.focused) {
return this.searchResult || [];
}
return [];
},
showIcon() {
return this.value && this.focused;
}
},
methods: {
onSelect(express) {
this.$emit('select-search', express);
this.$emit('input', `${express.address || ''} ${express.name || ''}`.trim());
}
}
});
</script>

View File

@ -1,115 +1,16 @@
<template>
<div :class="b()">
<field
v-model="data.name"
clearable
:label="$t('name')"
:placeholder="$t('namePlaceholder')"
:error="errorInfo.name"
@focus="onFocus('name')"
/>
<field
v-model="data.tel"
clearable
type="tel"
:label="$t('tel')"
:placeholder="$t('telPlaceholder')"
:error="errorInfo.tel"
@focus="onFocus('tel')"
/>
<field
v-show="showArea"
readonly
:label="$t('area')"
:placeholder="$t('areaPlaceholder')"
:value="areaText"
@click="showAreaPopup = true"
/>
<address-edit-detail
v-show="showDetail"
:focused="detailFocused"
:value="data.addressDetail"
:error="errorInfo.addressDetail"
:detail-rows="detailRows"
:search-result="searchResult"
:show-search-result="showSearchResult"
@focus="onFocus('addressDetail')"
@blur="detailFocused = false"
@input="onChangeDetail"
@select-search="$emit('select-search', $event)"
/>
<field
v-if="showPostal"
v-show="!hideBottomFields"
v-model="data.postalCode"
type="tel"
maxlength="6"
:label="$t('postal')"
:placeholder="$t('postal')"
:error="errorInfo.postalCode"
@focus="onFocus('postalCode')"
/>
<slot />
<switch-cell
v-if="showSetDefault"
v-show="!hideBottomFields"
v-model="data.isDefault"
:title="$t('defaultAddress')"
@change="$emit('change-default', $event)"
/>
<div
v-show="!hideBottomFields"
:class="b('buttons')"
>
<van-button
block
:loading="isSaving"
type="danger"
:text="saveButtonText || $t('save')"
@click="onSave"
/>
<van-button
v-if="showDelete"
block
:loading="isDeleting"
:text="deleteButtonText || $t('delete')"
@click="onDelete"
/>
</div>
<popup
v-model="showAreaPopup"
position="bottom"
:lazy-render="false"
get-container="body"
>
<van-area
ref="area"
:loading="!areaListLoaded"
:value="data.areaCode"
:area-list="areaList"
@confirm="onAreaConfirm"
@cancel="showAreaPopup = false"
/>
</popup>
</div>
</template>
<script>
/* eslint-disable camelcase */
import create from '../utils/create';
import { isObj } from '../utils';
import { use, isObj } from '../utils';
import Area from '../area';
import Field from '../field';
import VanButton from '../button';
import Popup from '../popup';
import Toast from '../toast';
import Button from '../button';
import Dialog from '../dialog';
import VanArea from '../area';
import AddressEditDetail from './Detail';
import Detail from './Detail';
import SwitchCell from '../switch-cell';
import validateMobile from '../utils/validate/mobile';
const [sfc, bem, t] = use('address-edit');
const defaultData = {
name: '',
tel: '',
@ -123,18 +24,7 @@ const defaultData = {
isDefault: false
};
export default create({
name: 'address-edit',
components: {
Field,
Popup,
VanArea,
VanButton,
SwitchCell,
AddressEditDetail
},
export default sfc({
props: {
areaList: Object,
isSaving: Boolean,
@ -276,7 +166,6 @@ export default create({
getErrorMessage(key) {
const value = String(this.data[key] || '').trim();
const { $t } = this;
if (this.validator) {
const message = this.validator(key, value);
@ -287,21 +176,21 @@ export default create({
switch (key) {
case 'name':
return value ? '' : $t('nameEmpty');
return value ? '' : t('nameEmpty');
case 'tel':
return this.telValidator(value) ? '' : $t('telInvalid');
return this.telValidator(value) ? '' : t('telInvalid');
case 'areaCode':
return value ? '' : $t('areaEmpty');
return value ? '' : t('areaEmpty');
case 'addressDetail':
return value ? '' : $t('addressEmpty');
return value ? '' : t('addressEmpty');
case 'postalCode':
return value && !/^\d{6}$/.test(value) ? $t('postalEmpty') : '';
return value && !/^\d{6}$/.test(value) ? t('postalEmpty') : '';
}
},
onDelete() {
Dialog.confirm({
title: this.$t('confirmDelete')
title: t('confirmDelete')
})
.then(() => {
this.$emit('delete', this.data);
@ -328,6 +217,116 @@ export default create({
setAddressDetail(value) {
this.data.addressDetail = value;
}
},
render(h) {
const { data, errorInfo, hideBottomFields } = this;
const onFocus = name => () => this.onFocus(name);
return (
<div class={bem()}>
<Field
v-model={data.name}
clearable
label={t('name')}
placeholder={t('namePlaceholder')}
error={errorInfo.name}
onFocus={onFocus('name')}
/>
<Field
v-model={data.tel}
clearable
type="tel"
label={t('tel')}
placeholder={t('telPlaceholder')}
error={errorInfo.tel}
onFocus={onFocus('tel')}
/>
<Field
v-show={this.showArea}
readonly
label={t('area')}
placeholder={t('areaPlaceholder')}
value={this.areaText}
onClick={() => {
this.showAreaPopup = true;
}}
/>
<Detail
v-show={this.showDetail}
focused={this.detailFocused}
value={data.addressDetail}
error={errorInfo.addressDetail}
detail-rows={this.detailRows}
search-result={this.searchResult}
show-search-result={this.showSearchResult}
onFocus={onFocus('addressDetail')}
onBlur={() => {
this.detailFocused = false;
}}
onInput={this.onChangeDetail}
onSelect-search={event => {
this.$emit('select-search', event);
}}
/>
{this.showPostal && (
<Field
v-show={!hideBottomFields}
v-model={data.postalCode}
type="tel"
maxlength="6"
label={t('postal')}
placeholder={t('postal')}
error={errorInfo.postalCode}
onFocus={onFocus('postalCode')}
/>
)}
{this.$slots.default}
{this.showSetDefault && (
<SwitchCell
v-model={data.isDefault}
v-show={!hideBottomFields}
title={t('defaultAddress')}
onChange={event => {
this.$emit('change-default', event);
}}
/>
)}
<div v-show={!hideBottomFields} class={bem('buttons')}>
<Button
block
loading={this.isSaving}
type="danger"
text={this.saveButtonText || t('save')}
onClick={this.onSave}
/>
{this.showDelete && (
<Button
block
loading={this.isDeleting}
text={this.deleteButtonText || t('delete')}
onClick={this.onDelete}
/>
)}
</div>
<Popup
v-model={this.showAreaPopup}
position="bottom"
lazy-render={false}
get-container="body"
>
<Area
ref="area"
loading={!this.areaListLoaded}
value={data.areaCode}
area-list={this.areaList}
onConfirm={this.onAreaConfirm}
onCancel={() => {
this.showAreaPopup = false;
}}
/>
</Popup>
</div>
);
}
});
</script>

View File

@ -75,6 +75,7 @@ exports[`renders demo correctly 1`] = `
</div>
</div>
<div class="van-cell van-cell--center van-cell--borderless van-switch-cell">
<div class="van-cell__title"><span>设为默认收货地址</span>
</div>
@ -87,7 +88,8 @@ exports[`renders demo correctly 1`] = `
</div>
</div>
<div class="van-address-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button> <button class="van-button van-button--default van-button--normal van-button--block"><span class="van-button__text">删除</span></button></div>
<div class="van-address-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button>
<button class="van-button van-button--default van-button--normal van-button--block"><span class="van-button__text">删除</span></button></div>
<div class="van-popup van-popup--bottom" style="display:none;">
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">

View File

@ -60,10 +60,10 @@ exports[`create a AddressEdit 1`] = `
</div>
</div>
<!---->
<!---->
<div class="van-address-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button>
<!---->
</div>
<div name="popup-slide-bottom" class="van-popup van-popup--bottom" style="display:none;">
<div class="van-picker van-area">
@ -165,6 +165,7 @@ exports[`create a AddressEdit with props 1`] = `
</div>
</div>
<div class="van-cell van-cell--center van-cell--borderless van-switch-cell">
<div class="van-cell__title"><span>设为默认收货地址</span>
</div>
@ -178,7 +179,6 @@ exports[`create a AddressEdit with props 1`] = `
</div>
<div class="van-address-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button>
<!---->
</div>
<div name="popup-slide-bottom" class="van-popup van-popup--bottom" style="display:none;">
<div class="van-picker van-area">