[improvement] use scoped-slots (#2712)

This commit is contained in:
neverland 2019-02-11 17:52:43 +08:00 committed by GitHub
parent 9f7c91a3b9
commit 9c4ad97731
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 159 additions and 122 deletions

View File

@ -19,29 +19,27 @@ export default sfc({
onSelect(express) { onSelect(express) {
this.$emit('select-search', express); this.$emit('select-search', express);
this.$emit('input', `${express.address || ''} ${express.name || ''}`.trim()); this.$emit('input', `${express.address || ''} ${express.name || ''}`.trim());
}
}, },
render(h) { onFinish() {
const { value, focused, searchResult } = this;
const Finish = value && focused && android && (
<div
slot="icon"
class={bem('finish')}
onClick={() => {
this.$refs.field.blur(); this.$refs.field.blur();
}} },
>
renderFinish() {
const showFinish = this.value && this.focused && android;
if (showFinish) {
return (
<div class={bem('finish')} onClick={this.onFinish}>
{t('complete')} {t('complete')}
</div> </div>
); );
}
},
const SearchList = renderSearchResult() {
focused && const showSearchList = this.focused && this.searchResult && this.showSearchResult;
searchResult && if (showSearchList) {
this.showSearchResult && return this.searchResult.map(express => (
searchResult.map(express => (
<Cell <Cell
key={express.name + express.address} key={express.name + express.address}
title={express.name} title={express.name}
@ -53,7 +51,11 @@ export default sfc({
}} }}
/> />
)); ));
}
}
},
render(h) {
return ( return (
<Cell class={bem()}> <Cell class={bem()}>
<Field <Field
@ -67,11 +69,10 @@ export default sfc({
error={this.error} error={this.error}
label={t('label')} label={t('label')}
placeholder={t('placeholder')} placeholder={t('placeholder')}
scopedSlots={{ icon: this.renderFinish }}
{...{ on: this.$listeners }} {...{ on: this.$listeners }}
> />
{Finish} {this.renderSearchResult()}
</Field>
{SearchList}
</Cell> </Cell>
); );
} }

View File

@ -17,33 +17,41 @@ export default sfc({
if (this.switchable) { if (this.switchable) {
this.$emit('select'); this.$emit('select');
} }
}
}, },
render(h) { onClickRightIcon(event) {
const { data, disabled, switchable } = this; event.stopPropagation();
this.$emit('edit');
},
renderRightIcon() {
return <Icon name="edit" class={bem('edit')} onClick={this.onClickRightIcon} />;
},
renderContent() {
const { data } = this;
const Info = [ const Info = [
<div class={bem('name')}>{`${data.name}${data.tel}`}</div>, <div class={bem('name')}>{`${data.name}${data.tel}`}</div>,
<div class={bem('address')}>{data.address}</div> <div class={bem('address')}>{data.address}</div>
]; ];
return this.disabled ? Info : <Radio name={data.id}>{Info}</Radio>;
}
},
render(h) {
const { disabled, switchable } = this;
return ( return (
<Cell <Cell
class={bem({ disabled, unswitchable: !switchable })} class={bem({ disabled, unswitchable: !switchable })}
isLink={!disabled && switchable} isLink={!disabled && switchable}
onClick={this.onSelect} scopedSlots={{
> default: this.renderContent,
{disabled ? Info : <Radio name={data.id}>{Info}</Radio>} 'right-icon': this.renderRightIcon
<Icon
slot="right-icon"
name="edit"
class={bem('edit')}
onClick={event => {
event.stopPropagation();
this.$emit('edit');
}} }}
onClick={this.onSelect}
/> />
</Cell>
); );
} }
}); });

View File

@ -23,16 +23,14 @@ export default sfc({
<Cell <Cell
key={item.id} key={item.id}
isLink isLink
onClick={() => { scopedSlots={{
listeners.input && listeners.input(item.id); default: () => (
listeners.select && listeners.select(item, index);
}}
>
<Radio name={item.id}> <Radio name={item.id}>
<div class={bem('name')}>{`${item.name}${item.tel}`}</div> <div class={bem('name')}>{`${item.name}${item.tel}`}</div>
</Radio> </Radio>
),
'right-icon': () => (
<Icon <Icon
slot="right-icon"
name="edit" name="edit"
class={bem('edit')} class={bem('edit')}
onClick={event => { onClick={event => {
@ -40,7 +38,13 @@ export default sfc({
listeners.edit && listeners.edit(item, index); listeners.edit && listeners.edit(item, index);
}} }}
/> />
</Cell> )
}}
onClick={() => {
listeners.input && listeners.input(item.id);
listeners.select && listeners.select(item, index);
}}
/>
)); ));
return ( return (

View File

@ -123,6 +123,29 @@ export default sfc({
list.scrollTop = card[index].$el.offsetTop - 100; list.scrollTop = card[index].$el.offsetTop - 100;
} }
}); });
},
renderEmpty() {
return (
<div class={bem('empty')}>
<img src={EMPTY_IMAGE} />
<p>{t('empty')}</p>
</div>
);
},
renderExchangeButton() {
return (
<Button
size="small"
type="danger"
class={bem('exchange')}
text={this.exchangeButtonText || t('exchange')}
loading={this.exchangeButtonLoading}
disabled={this.buttonDisabled}
onClick={this.onClickExchangeButton}
/>
);
} }
}, },
@ -135,25 +158,10 @@ export default sfc({
class={bem('field')} class={bem('field')}
placeholder={this.inputPlaceholder || t('placeholder')} placeholder={this.inputPlaceholder || t('placeholder')}
maxlength="20" maxlength="20"
> scopedSlots={{
<Button button: this.renderExchangeButton
slot="button" }}
size="small"
type="danger"
class={bem('exchange')}
text={this.exchangeButtonText || t('exchange')}
loading={this.exchangeButtonLoading}
disabled={this.buttonDisabled}
onClick={this.onClickExchangeButton}
/> />
</Field>
);
const Empty = (
<div class={bem('empty')}>
<img src={EMPTY_IMAGE} />
<p>{t('empty')}</p>
</div>
); );
const onChange = index => () => this.$emit('change', index); const onChange = index => () => this.$emit('change', index);
@ -171,7 +179,7 @@ export default sfc({
nativeOnClick={onChange(index)} nativeOnClick={onChange(index)}
/> />
))} ))}
{!this.coupons.length && Empty} {!this.coupons.length && this.renderEmpty()}
</div> </div>
</Tab> </Tab>
); );
@ -182,7 +190,7 @@ export default sfc({
{this.disabledCoupons.map(coupon => ( {this.disabledCoupons.map(coupon => (
<Coupon disabled key={coupon.id} coupon={coupon} currency={this.currency} /> <Coupon disabled key={coupon.id} coupon={coupon} currency={this.currency} />
))} ))}
{!this.disabledCoupons.length && Empty} {!this.disabledCoupons.length && this.renderEmpty}
</div> </div>
</Tab> </Tab>
); );

View File

@ -163,26 +163,9 @@ export default sfc({
if (height) { if (height) {
input.style.height = height + 'px'; input.style.height = height + 'px';
} }
}
}, },
render(h) { renderInput() {
const { type, labelAlign, slots } = this;
const showLeftIcon = slots('left-icon') || this.leftIcon;
const showRightIcon = slots('right-icon') || slots('icon') || this.rightIcon || this.icon;
const LeftIcon = showLeftIcon && (
<div slot="icon" class={bem('left-icon')} onClick={this.onClickLeftIcon}>
{slots('left-icon') || <Icon name={this.leftIcon} />}
</div>
);
const RightIcon = showRightIcon && (
<div class={bem('right-icon')} onClick={this.onClickRightIcon}>
{slots('right-icon') || slots('icon') || <Icon name={this.rightIcon || this.icon} />}
</div>
);
const inputProps = { const inputProps = {
ref: 'input', ref: 'input',
class: bem('control', this.inputAlign), class: bem('control', this.inputAlign),
@ -196,8 +179,39 @@ export default sfc({
on: this.listeners on: this.listeners
}; };
const Input = type === 'textarea' ? <textarea {...inputProps} /> : <input type={type} {...inputProps} />; if (this.type === 'textarea') {
return <textarea {...inputProps} />;
}
return <input type={this.type} {...inputProps} />;
},
renderLeftIcon() {
const showLeftIcon = this.slots('left-icon') || this.leftIcon;
if (showLeftIcon) {
return (
<div class={bem('left-icon')} onClick={this.onClickLeftIcon}>
{this.slots('left-icon') || <Icon name={this.leftIcon} />}
</div>
);
}
},
renderRightIcon() {
const { slots } = this;
const showRightIcon = slots('right-icon') || slots('icon') || this.rightIcon || this.icon;
if (showRightIcon) {
return (
<div class={bem('right-icon')} onClick={this.onClickRightIcon}>
{slots('right-icon') || slots('icon') || <Icon name={this.rightIcon || this.icon} />}
</div>
);
}
}
},
render(h) {
const { slots, labelAlign } = this;
return ( return (
<Cell <Cell
icon={this.leftIcon} icon={this.leftIcon}
@ -210,15 +224,17 @@ export default sfc({
error: this.error, error: this.error,
disabled: this.$attrs.disabled, disabled: this.$attrs.disabled,
[`label-${labelAlign}`]: labelAlign, [`label-${labelAlign}`]: labelAlign,
'min-height': type === 'textarea' && !this.autosize 'min-height': this.type === 'textarea' && !this.autosize
})} })}
scopedSlots={{
icon: this.renderLeftIcon
}}
> >
{LeftIcon}
{h('template', { slot: 'title' }, slots('label'))} {h('template', { slot: 'title' }, slots('label'))}
<div class={bem('body')}> <div class={bem('body')}>
{Input} {this.renderInput()}
{this.showClear && <Icon name="clear" class={bem('clear')} onTouchstart={this.onClear} />} {this.showClear && <Icon name="clear" class={bem('clear')} onTouchstart={this.onClear} />}
{RightIcon} {this.renderRightIcon()}
{slots('button') && <div class={bem('button')}>{slots('button')}</div>} {slots('button') && <div class={bem('button')}>{slots('button')}</div>}
</div> </div>
{this.errorMessage && <div class={bem('error-message')}>{this.errorMessage}</div>} {this.errorMessage && <div class={bem('error-message')}>{this.errorMessage}</div>}