mirror of
https://github.com/youzan/vant.git
synced 2025-10-19 18:14:13 +00:00
[improvement] Picker: jsx (#2613)
This commit is contained in:
196
packages/picker/index.js
Normal file
196
packages/picker/index.js
Normal file
@@ -0,0 +1,196 @@
|
||||
import { use } from '../utils';
|
||||
import Loading from '../loading';
|
||||
import PickerColumn from './PickerColumn';
|
||||
import deepClone from '../utils/deep-clone';
|
||||
import PickerMixin from '../mixins/picker';
|
||||
|
||||
const [sfc, bem, t] = use('picker');
|
||||
|
||||
export default sfc({
|
||||
mixins: [PickerMixin],
|
||||
|
||||
props: {
|
||||
columns: Array,
|
||||
valueKey: {
|
||||
type: String,
|
||||
default: 'text'
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
children: []
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
simple() {
|
||||
return this.columns.length && !this.columns[0].values;
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
columns() {
|
||||
this.setColumns();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
setColumns() {
|
||||
const columns = this.simple ? [{ values: this.columns }] : this.columns;
|
||||
columns.forEach((column, index) => {
|
||||
this.setColumnValues(index, deepClone(column.values));
|
||||
});
|
||||
},
|
||||
|
||||
emit(event) {
|
||||
if (this.simple) {
|
||||
this.$emit(event, this.getColumnValue(0), this.getColumnIndex(0));
|
||||
} else {
|
||||
this.$emit(event, this.getValues(), this.getIndexes());
|
||||
}
|
||||
},
|
||||
|
||||
onChange(columnIndex) {
|
||||
if (this.simple) {
|
||||
this.$emit('change', this, this.getColumnValue(0), this.getColumnIndex(0));
|
||||
} else {
|
||||
this.$emit('change', this, this.getValues(), columnIndex);
|
||||
}
|
||||
},
|
||||
|
||||
// get column instance by index
|
||||
getColumn(index) {
|
||||
return this.children[index];
|
||||
},
|
||||
|
||||
// get column value by index
|
||||
getColumnValue(index) {
|
||||
const column = this.getColumn(index);
|
||||
return column && column.getValue();
|
||||
},
|
||||
|
||||
// set column value by index
|
||||
setColumnValue(index, value) {
|
||||
const column = this.getColumn(index);
|
||||
column && column.setValue(value);
|
||||
},
|
||||
|
||||
// get column option index by column index
|
||||
getColumnIndex(columnIndex) {
|
||||
return (this.getColumn(columnIndex) || {}).currentIndex;
|
||||
},
|
||||
|
||||
// set column option index by column index
|
||||
setColumnIndex(columnIndex, optionIndex) {
|
||||
const column = this.getColumn(columnIndex);
|
||||
column && column.setIndex(optionIndex);
|
||||
},
|
||||
|
||||
// get options of column by index
|
||||
getColumnValues(index) {
|
||||
return (this.children[index] || {}).options;
|
||||
},
|
||||
|
||||
// set options of column by index
|
||||
setColumnValues(index, options) {
|
||||
const column = this.children[index];
|
||||
if (column && JSON.stringify(column.options) !== JSON.stringify(options)) {
|
||||
column.options = options;
|
||||
column.setIndex(0);
|
||||
}
|
||||
},
|
||||
|
||||
// get values of all columns
|
||||
getValues() {
|
||||
return this.children.map(child => child.getValue());
|
||||
},
|
||||
|
||||
// set values of all columns
|
||||
setValues(values) {
|
||||
values.forEach((value, index) => {
|
||||
this.setColumnValue(index, value);
|
||||
});
|
||||
},
|
||||
|
||||
// get indexes of all columns
|
||||
getIndexes() {
|
||||
return this.children.map(child => child.currentIndex);
|
||||
},
|
||||
|
||||
// set indexes of all columns
|
||||
setIndexes(indexes) {
|
||||
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>
|
||||
);
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user