UNPKG

lulouis-vant

Version:

Lightweight Mobile UI Components built on Vue

208 lines (184 loc) 4.9 kB
import { use } from '../utils'; import Tab from '../tab'; import Tabs from '../tabs'; import Field from '../field'; import Button from '../button'; import Coupon from '../coupon'; const [sfc, bem, t] = use('coupon-list'); const EMPTY_IMAGE = 'https://img.yzcdn.cn/v2/image/wap/trade/new_order/empty@2x.png'; export default sfc({ model: { prop: 'code' }, props: { code: String, coupons: Array, disabledCoupons: Array, closeButtonText: String, inputPlaceholder: String, exchangeButtonText: String, exchangeButtonLoading: Boolean, exchangeButtonDisabled: Boolean, exchangeMinLength: { type: Number, default: 1 }, chosenCoupon: { type: Number, default: -1 }, displayedCouponIndex: { type: Number, default: -1 }, showExchangeBar: { type: Boolean, default: true }, showCloseButton: { type: Boolean, default: true }, currency: { type: String, default: '¥' } }, data() { return { tab: 0, winHeight: window.innerHeight, currentCode: this.code || '' }; }, computed: { buttonDisabled() { return ( !this.exchangeButtonLoading && (this.exchangeButtonDisabled || !this.currentCode || this.currentCode.length < this.exchangeMinLength) ); }, title() { return `${t('enable')} (${this.coupons.length})`; }, disabledTitle() { return `${t('disabled')} (${this.disabledCoupons.length})`; }, listStyle() { return { height: this.winHeight - (this.showExchangeBar ? 140 : 94) + 'px' }; } }, watch: { code(code) { this.currentCode = code; }, currentCode(code) { this.$emit('input', code); }, displayedCouponIndex(val) { this.scrollToShowCoupon(val); } }, mounted() { this.scrollToShowCoupon(this.displayedCouponIndex); }, methods: { onClickExchangeButton() { this.$emit('exchange', this.currentCode); // auto clear currentCode when not use v-model if (!this.code) { this.currentCode = ''; } }, // scroll to show specific coupon scrollToShowCoupon(index) { if (index === -1) { return; } this.$nextTick(() => { const { card, list } = this.$refs; /* istanbul ignore next */ if (list && card && card[index]) { list.scrollTop = card[index].$el.offsetTop - 100; } }); } }, render(h) { const ExchangeBar = this.showExchangeBar && ( <Field v-model={this.currentCode} clearable border={false} class={bem('field')} placeholder={this.inputPlaceholder || t('placeholder')} maxlength="20" > <Button 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 CouponTab = ( <Tab title={this.title}> <div class={bem('list')} style={this.listStyle}> {this.coupons.map((coupon, index) => ( <Coupon ref="card" key={coupon.id} coupon={coupon} currency={this.currency} chosen={index === this.chosenCoupon} nativeOnClick={onChange(index)} /> ))} {!this.coupons.length && Empty} </div> </Tab> ); const DisabledCouponTab = ( <Tab title={this.disabledTitle}> <div class={bem('list')} style={this.listStyle}> {this.disabledCoupons.map(coupon => ( <Coupon disabled key={coupon.id} coupon={coupon} currency={this.currency} /> ))} {!this.disabledCoupons.length && Empty} </div> </Tab> ); return ( <div class={bem()}> {ExchangeBar} <Tabs v-model={this.tab} class={bem('tab')} line-width={120}> {CouponTab} {DisabledCouponTab} </Tabs> <Button v-show={this.showCloseButton} size="large" class={bem('close')} text={this.closeButtonText || t('close')} onClick={onChange(-1)} /> </div> ); } });