mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[Improvement] Picker: optimize render performance (#1391)
This commit is contained in:
parent
6adf501441
commit
7f4ad6a28d
@ -25,6 +25,7 @@
|
||||
|
||||
<script>
|
||||
import create from '../utils/create';
|
||||
import deepClone from '../utils/deep-clone';
|
||||
import { isObj } from '../utils';
|
||||
|
||||
const DEFAULT_DURATION = 200;
|
||||
@ -38,7 +39,7 @@ export default create({
|
||||
className: String,
|
||||
itemHeight: Number,
|
||||
visibleItemCount: Number,
|
||||
options: {
|
||||
initialOptions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
@ -54,15 +55,13 @@ export default create({
|
||||
offset: 0,
|
||||
duration: 0,
|
||||
startOffset: 0,
|
||||
options: deepClone(this.initialOptions),
|
||||
currentIndex: this.defaultIndex
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.$parent.children && this.$parent.children.push(this);
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.setIndex(this.currentIndex);
|
||||
},
|
||||
|
||||
@ -73,12 +72,6 @@ export default create({
|
||||
watch: {
|
||||
defaultIndex() {
|
||||
this.setIndex(this.defaultIndex);
|
||||
},
|
||||
|
||||
options(next, prev) {
|
||||
if (JSON.stringify(next) !== JSON.stringify(prev)) {
|
||||
this.setIndex(0);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -103,10 +96,6 @@ export default create({
|
||||
transform: `translate3d(0, ${this.offset + this.baseOffset}px, 0)`,
|
||||
lineHeight: this.itemHeight + 'px'
|
||||
};
|
||||
},
|
||||
|
||||
currentValue() {
|
||||
return this.options[this.currentIndex];
|
||||
}
|
||||
},
|
||||
|
||||
@ -168,10 +157,13 @@ export default create({
|
||||
const { options } = this;
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
if (this.getOptionText(options[i]) === value) {
|
||||
this.setIndex(i);
|
||||
return;
|
||||
return this.setIndex(i);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getValue() {
|
||||
return this.options[this.currentIndex];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -12,10 +12,10 @@
|
||||
</div>
|
||||
<div :class="b('columns')" :style="columnsStyle" @touchmove.prevent>
|
||||
<picker-column
|
||||
v-for="(item, index) in currentColumns"
|
||||
v-for="(item, index) in (simple ? [columns] : columns)"
|
||||
:key="index"
|
||||
:value-key="valueKey"
|
||||
:options="item.values"
|
||||
:initial-options="simple ? item : item.values"
|
||||
:class-name="item.className"
|
||||
:default-index="item.defaultIndex"
|
||||
:item-height="itemHeight"
|
||||
@ -65,22 +65,10 @@ export default create({
|
||||
|
||||
data() {
|
||||
return {
|
||||
children: [],
|
||||
currentColumns: []
|
||||
children: []
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
columns: {
|
||||
handler() {
|
||||
const columns = this.columns.map(deepClone);
|
||||
this.isSimpleColumn = columns.length && !columns[0].values;
|
||||
this.currentColumns = this.isSimpleColumn ? [{ values: columns }] : columns;
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
frameStyle() {
|
||||
return {
|
||||
@ -92,12 +80,29 @@ export default create({
|
||||
return {
|
||||
height: this.itemHeight * this.visibleItemCount + 'px'
|
||||
};
|
||||
},
|
||||
|
||||
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((columns, index) => {
|
||||
this.setColumnValues(index, deepClone(columns.values));
|
||||
});
|
||||
},
|
||||
|
||||
emit(event) {
|
||||
if (this.isSimpleColumn) {
|
||||
if (this.simple) {
|
||||
this.$emit(event, this.getColumnValue(0), this.getColumnIndex(0));
|
||||
} else {
|
||||
this.$emit(event, this.getValues(), this.getIndexes());
|
||||
@ -105,7 +110,7 @@ export default create({
|
||||
},
|
||||
|
||||
onChange(columnIndex) {
|
||||
if (this.isSimpleColumn) {
|
||||
if (this.simple) {
|
||||
this.$emit('change', this, this.getColumnValue(0), this.getColumnIndex(0));
|
||||
} else {
|
||||
this.$emit('change', this, this.getValues(), columnIndex);
|
||||
@ -119,7 +124,8 @@ export default create({
|
||||
|
||||
// get column value by index
|
||||
getColumnValue(index) {
|
||||
return (this.getColumn(index) || {}).currentValue;
|
||||
const column = this.getColumn(index);
|
||||
return column && column.getValue();
|
||||
},
|
||||
|
||||
// set column value by index
|
||||
@ -141,20 +147,21 @@ export default create({
|
||||
|
||||
// get options of column by index
|
||||
getColumnValues(index) {
|
||||
return (this.currentColumns[index] || {}).values;
|
||||
return (this.children[index] || {}).options;
|
||||
},
|
||||
|
||||
// set options of column by index
|
||||
setColumnValues(index, options) {
|
||||
const column = this.currentColumns[index];
|
||||
if (column) {
|
||||
column.values = 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.currentValue);
|
||||
return this.children.map(child => child.getValue());
|
||||
},
|
||||
|
||||
// set values of all columns
|
||||
|
@ -26,9 +26,9 @@ exports[`renders demo correctly 1`] = `
|
||||
<!---->
|
||||
<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;">
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--disabled van-picker-column__item--selected">杭州</li>
|
||||
<li class="van-ellipsis van-picker-column__item">宁波</li>
|
||||
<ul style="transition:0ms;transform:translate3d(0, 44px, 0);line-height:44px;">
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--disabled">杭州</li>
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--selected">宁波</li>
|
||||
<li class="van-ellipsis van-picker-column__item">温州</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -70,7 +70,7 @@ exports[`renders demo correctly 1`] = `
|
||||
</ul>
|
||||
</div>
|
||||
<div class="van-picker-column column2" style="height:220px;">
|
||||
<ul style="transition:0ms;transform:translate3d(0, 88px, 0);line-height:44px;">
|
||||
<ul style="transition:0ms;transform:translate3d(0, 0px, 0);line-height:44px;">
|
||||
<li class="van-ellipsis van-picker-column__item">杭州</li>
|
||||
<li class="van-ellipsis van-picker-column__item">宁波</li>
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--selected">温州</li>
|
||||
@ -96,7 +96,7 @@ exports[`renders demo correctly 1`] = `
|
||||
</ul>
|
||||
</div>
|
||||
<div class="van-picker-column column2" style="height:220px;">
|
||||
<ul style="transition:0ms;transform:translate3d(0, 88px, 0);line-height:44px;">
|
||||
<ul style="transition:0ms;transform:translate3d(0, 0px, 0);line-height:44px;">
|
||||
<li class="van-ellipsis van-picker-column__item">杭州</li>
|
||||
<li class="van-ellipsis van-picker-column__item">宁波</li>
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--selected">温州</li>
|
||||
|
@ -18,8 +18,8 @@ exports[`column watch default index 2`] = `
|
||||
<div class="van-picker-column">
|
||||
<ul style="line-height: 50px;">
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--disabled">1</li>
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--selected">1990</li>
|
||||
<li class="van-ellipsis van-picker-column__item">1991</li>
|
||||
<li class="van-ellipsis van-picker-column__item">1990</li>
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--selected">1991</li>
|
||||
<li class="van-ellipsis van-picker-column__item">1992</li>
|
||||
<li class="van-ellipsis van-picker-column__item">1993</li>
|
||||
<li class="van-ellipsis van-picker-column__item">1994</li>
|
||||
@ -27,14 +27,3 @@ exports[`column watch default index 2`] = `
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`column watch default index 3`] = `
|
||||
<div class="van-picker-column">
|
||||
<ul style="line-height: 50px;">
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--selected">1</li>
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--disabled">1</li>
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--disabled">1</li>
|
||||
<li class="van-ellipsis van-picker-column__item van-picker-column__item--disabled">1</li>
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Picker from '../';
|
||||
import PickerColumn from '../PickerColumn';
|
||||
import { mount, triggerDrag } from '../../../test/utils';
|
||||
import { mount, triggerDrag, later } from '../../../test/utils';
|
||||
|
||||
const simpleColumn = ['1990', '1991', '1992', '1993', '1994', '1995'];
|
||||
const columns = [
|
||||
@ -101,21 +101,19 @@ test('drag simple columns', () => {
|
||||
expect(wrapper.emitted('change')[0][1]).toEqual('1992');
|
||||
});
|
||||
|
||||
test('column watch default index', () => {
|
||||
test('column watch default index', async() => {
|
||||
const disabled = { disabled: true, text: 1 };
|
||||
const wrapper = mount(PickerColumn, {
|
||||
propsData: {
|
||||
initialOptions: [disabled, ...simpleColumn],
|
||||
valueKey: 'text',
|
||||
itemHeight: 50
|
||||
}
|
||||
});
|
||||
wrapper.vm.options = [disabled, ...simpleColumn];
|
||||
|
||||
await later();
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
wrapper.vm.options = [disabled, ...simpleColumn];
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
wrapper.vm.options = [1, disabled, disabled, disabled];
|
||||
wrapper.vm.defaultIndex = 2;
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user