[improvement] Picker: jsx (#2613)

This commit is contained in:
neverland 2019-01-25 19:15:22 +08:00 committed by GitHub
parent 30159884b4
commit 6505ae7705
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 128 additions and 177 deletions

View File

@ -53,10 +53,8 @@ exports[`renders demo correctly 1`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height:220px;">
<div class="van-picker-column" style="height:220px;">
<ul style="transition:0ms;transform:translate3d(0, 88px, 0);line-height:44px;"></ul>

View File

@ -35,7 +35,6 @@ exports[`create a AddressEdit 1`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<div class="van-picker__loading">
@ -109,10 +108,8 @@ exports[`create a AddressEdit with props 1`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height:220px;">
<div class="van-picker-column" style="height:220px;">
<ul style="transition:0ms;transform:translate3d(0, 88px, 0);line-height:44px;"></ul>

View File

@ -6,10 +6,8 @@ exports[`renders demo correctly 1`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height:220px;">
<div class="van-picker-column" style="height:220px;">
<ul style="transition:0ms;transform:translate3d(0, 88px, 0);line-height:44px;"></ul>
@ -28,10 +26,8 @@ exports[`renders demo correctly 1`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height:220px;">
<div class="van-picker-column" style="height:220px;">
<ul style="transition:0ms;transform:translate3d(0, 88px, 0);line-height:44px;"></ul>
@ -53,7 +49,6 @@ exports[`renders demo correctly 1`] = `
<div class="van-ellipsis van-picker__title">标题</div>
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height:220px;">
<div class="van-picker-column" style="height:220px;">
<ul style="transition:0ms;transform:translate3d(0, 88px, 0);line-height:44px;"></ul>

View File

@ -4,10 +4,8 @@ exports[`change option 1`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height: 220px;">
<div class="van-picker-column" style="height: 220px;">
<ul style="transform: translate3d(0, 88px, 0); line-height: 44px;"></ul>
@ -27,10 +25,8 @@ exports[`change option 2`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height: 220px;">
<div class="van-picker-column" style="height: 220px;">
<ul style="transform: translate3d(0, 44px, 0); line-height: 44px;">
@ -59,10 +55,8 @@ exports[`change option 3`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height: 220px;">
<div class="van-picker-column" style="height: 220px;">
<ul style="transform: translate3d(0, 44px, 0); line-height: 44px;">
@ -91,10 +85,8 @@ exports[`reset method 1`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height: 220px;">
<div class="van-picker-column" style="height: 220px;">
<ul style="transform: translate3d(0, 44px, 0); line-height: 44px;">
@ -122,10 +114,8 @@ exports[`reset method 2`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height: 220px;">
<div class="van-picker-column" style="height: 220px;">
<ul style="transform: translate3d(0, 88px, 0); line-height: 44px;">
@ -154,10 +144,8 @@ exports[`watch areaList & code 1`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height: 220px;">
<div class="van-picker-column" style="height: 220px;">
<ul style="transform: translate3d(0, 88px, 0); line-height: 44px;"></ul>
@ -177,10 +165,8 @@ exports[`watch areaList & code 2`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height: 220px;">
<div class="van-picker-column" style="height: 220px;">
<ul style="transform: translate3d(0, 88px, 0); line-height: 44px;">
@ -209,10 +195,8 @@ exports[`watch areaList & code 3`] = `
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
<div class="van-picker__cancel">取消</div>
<!---->
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height: 220px;">
<div class="van-picker-column" style="height: 220px;">
<ul style="transform: translate3d(0, 88px, 0); line-height: 44px;">

View File

@ -1,39 +1,10 @@
<template>
<div
:class="[b(), className]"
:style="columnStyle"
@touchstart="onTouchStart"
@touchmove.prevent="onTouchMove"
@touchend="onTouchEnd"
@touchcancel="onTouchEnd"
>
<ul :style="wrapperStyle">
<li
v-for="(option, index) in options"
v-html="getOptionText(option)"
:style="optionStyle"
class="van-ellipsis"
:class="b('item', {
disabled: isDisabled(option),
selected: index === currentIndex
})"
@click="setIndex(index, true)"
/>
</ul>
</div>
</template>
<script>
import create from '../utils/create';
import deepClone from '../utils/deep-clone';
import { isObj, range } from '../utils';
import { use, isObj, range } from '../utils';
const DEFAULT_DURATION = 200;
const [sfc, bem] = use('picker-column');
export default create({
name: 'picker-column',
export default sfc({
props: {
valueKey: String,
className: String,
@ -73,30 +44,6 @@ export default create({
computed: {
count() {
return this.options.length;
},
baseOffset() {
return this.itemHeight * (this.visibleItemCount - 1) / 2;
},
columnStyle() {
return {
height: this.itemHeight * this.visibleItemCount + 'px'
};
},
wrapperStyle() {
return {
transition: `${this.duration}ms`,
transform: `translate3d(0, ${this.offset + this.baseOffset}px, 0)`,
lineHeight: this.itemHeight + 'px'
};
},
optionStyle() {
return {
height: this.itemHeight + 'px'
};
}
},
@ -108,6 +55,7 @@ export default create({
},
onTouchMove(event) {
event.preventDefault();
const deltaY = event.touches[0].clientY - this.startY;
this.offset = range(
this.startOffset + deltaY,
@ -119,11 +67,7 @@ export default create({
onTouchEnd() {
if (this.offset !== this.startOffset) {
this.duration = DEFAULT_DURATION;
const index = range(
Math.round(-this.offset / this.itemHeight),
0,
this.count - 1
);
const index = range(Math.round(-this.offset / this.itemHeight), 0, this.count - 1);
this.setIndex(index, true);
}
},
@ -143,9 +87,7 @@ export default create({
},
getOptionText(option) {
return isObj(option) && this.valueKey in option
? option[this.valueKey]
: option;
return isObj(option) && this.valueKey in option ? option[this.valueKey] : option;
},
setIndex(index, userAction) {
@ -170,6 +112,55 @@ export default create({
getValue() {
return this.options[this.currentIndex];
}
},
render(h) {
const { itemHeight, visibleItemCount } = this;
const columnStyle = {
height: itemHeight * visibleItemCount + 'px'
};
const baseOffset = (itemHeight * (visibleItemCount - 1)) / 2;
const wrapperStyle = {
transition: `${this.duration}ms`,
transform: `translate3d(0, ${this.offset + baseOffset}px, 0)`,
lineHeight: `${itemHeight}px`
};
const optionStyle = {
height: `${itemHeight}px`
};
return (
<div
style={columnStyle}
class={[bem(), this.className]}
onTouchstart={this.onTouchStart}
onTouchmove={this.onTouchMove}
onTouchend={this.onTouchEnd}
onTouchcancel={this.onTouchEnd}
>
<ul style={wrapperStyle}>
{this.options.map((option, index) => (
<li
style={optionStyle}
class={[
'van-ellipsis',
bem('item', {
disabled: this.isDisabled(option),
selected: index === this.currentIndex
})
]}
domPropsInnerHTML={this.getOptionText(option)}
onClick={() => {
this.setIndex(index, true);
}}
/>
))}
</ul>
</div>
);
}
});
</script>

View File

@ -1,75 +1,14 @@
<template>
<div :class="b()">
<div
v-if="showToolbar"
:class="b('toolbar')"
class="van-hairline--top-bottom"
>
<slot>
<div
v-text="cancelButtonText || $t('cancel')"
:class="b('cancel')"
@click="emit('cancel')"
/>
<div
v-if="title"
v-text="title"
:class="b('title')"
class="van-ellipsis"
/>
<div
v-text="confirmButtonText || $t('confirm')"
:class="b('confirm')"
@click="emit('confirm')"
/>
</slot>
</div>
<div
v-if="loading"
:class="b('loading')"
>
<loading />
</div>
<div
:class="b('columns')"
:style="columnsStyle"
@touchmove.prevent
>
<picker-column
v-for="(item, index) in (simple ? [columns] : columns)"
:key="index"
:value-key="valueKey"
:initial-options="simple ? item : item.values"
:class-name="item.className"
:default-index="item.defaultIndex"
:item-height="itemHeight"
:visible-item-count="visibleItemCount"
@change="onChange(index)"
/>
<div
:class="b('frame')"
class="van-hairline--top-bottom"
:style="frameStyle"
/>
</div>
</div>
</template>
<script>
import create from '../utils/create';
import { use } from '../utils';
import Loading from '../loading';
import PickerColumn from './PickerColumn';
import deepClone from '../utils/deep-clone';
import PickerMixin from '../mixins/picker';
export default create({
name: 'picker',
const [sfc, bem, t] = use('picker');
export default sfc({
mixins: [PickerMixin],
components: {
PickerColumn
},
props: {
columns: Array,
valueKey: {
@ -85,18 +24,6 @@ export default create({
},
computed: {
frameStyle() {
return {
height: this.itemHeight + 'px'
};
},
columnsStyle() {
return {
height: this.itemHeight * this.visibleItemCount + 'px'
};
},
simple() {
return this.columns.length && !this.columns[0].values;
}
@ -196,7 +123,74 @@ export default create({
indexes.forEach((optionIndex, columnIndex) => {
this.setColumnIndex(columnIndex, optionIndex);
});
},
onConfirm() {
this.emit('confirm');
},
onCancel() {
this.emit('cancel');
}
},
render(h) {
const { itemHeight } = this;
const columns = this.simple ? [this.columns] : this.columns;
const frameStyle = {
height: `${itemHeight}px`
};
const columnsStyle = {
height: `${itemHeight * this.visibleItemCount}px`
};
const Toolbar = this.showToolbar && (
<div class={['van-hairline--top-bottom', bem('toolbar')]}>
{this.$slots.default || [
<div class={bem('cancel')} onClick={this.onCancel}>
{this.cancelButtonText || t('cancel')}
</div>,
this.title && <div class={['van-ellipsis', bem('title')]}>{this.title}</div>,
<div class={bem('confirm')} onClick={this.onConfirm}>
{this.confirmButtonText || t('confirm')}
</div>
]}
</div>
);
return (
<div class={bem()}>
{Toolbar}
{this.loading && (
<div class={bem('loading')}>
<Loading />
</div>
)}
<div
class={bem('columns')}
style={columnsStyle}
onTouchmove={event => {
event.preventDefault();
}}
>
{columns.map((item, index) => (
<PickerColumn
valueKey={this.valueKey}
className={item.className}
itemHeight={this.itemHeight}
defaultIndex={item.defaultIndex}
visibleItemCount={this.visibleItemCount}
initialOptions={this.simple ? item : item.values}
onChange={() => {
this.onChange(index);
}}
/>
))}
<div class={['van-hairline--top-bottom', bem('frame')]} style={frameStyle} />
</div>
</div>
);
}
});
</script>

View File

@ -4,8 +4,6 @@ exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-picker">
<!---->
<!---->
<div class="van-picker__columns" style="height:220px;">
<div class="van-picker-column" style="height:220px;">
<ul style="transition:0ms;transform:translate3d(0, 88px, 0);line-height:44px;">
@ -22,8 +20,6 @@ exports[`renders demo correctly 1`] = `
</div>
<div>
<div class="van-picker">
<!---->
<!---->
<div class="van-picker__columns" style="height:220px;">
<div class="van-picker-column" style="height:220px;">
<ul style="transition:0ms;transform:translate3d(0, 44px, 0);line-height:44px;">
@ -43,7 +39,6 @@ exports[`renders demo correctly 1`] = `
<div class="van-ellipsis van-picker__title">标题</div>
<div class="van-picker__confirm">确认</div>
</div>
<!---->
<div class="van-picker__columns" style="height:220px;">
<div class="van-picker-column" style="height:220px;">
<ul style="transition:0ms;transform:translate3d(0, 88px, 0);line-height:44px;">
@ -60,8 +55,6 @@ exports[`renders demo correctly 1`] = `
</div>
<div>
<div class="van-picker">
<!---->
<!---->
<div class="van-picker__columns" style="height:220px;">
<div class="van-picker-column column1" style="height:220px;">
<ul style="transition:0ms;transform:translate3d(0, 88px, 0);line-height:44px;">
@ -84,7 +77,6 @@ exports[`renders demo correctly 1`] = `
</div>
<div>
<div class="van-picker">
<!---->
<div class="van-picker__loading">
<div class="van-loading van-loading--circular van-loading" style="color:#c9c9c9;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--circular"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
</div>