From 4deba40870713412c6c950f6241e094a9b059a58 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Sat, 18 Jan 2020 13:28:20 +0800 Subject: [PATCH] perf(transfer): use many tricks to improve performance --- .../components/transfer/enUS/basic.md | 11 +- packages/common/Checkbox/src/Checkbox.vue | 5 +- .../common/Checkbox/src/SimpleCheckbox.vue | 85 ++++ packages/common/Transfer/index.js | 2 + packages/common/Transfer/src/Transfer.vue | 414 ++++++++++-------- .../common/Transfer/src/TransferButton.vue | 20 +- .../Transfer/src/TransferHeaderCheckbox.vue | 55 +++ .../Transfer/src/TransferHeaderExtra.vue | 32 ++ .../common/Transfer/src/TransferLightBar.vue | 39 ++ .../common/Transfer/src/TransferListItem.vue | 100 ----- .../Transfer/src/TransferSourceListItem.vue | 104 +++++ .../Transfer/src/TransferTargetListItem.vue | 104 +++++ .../utils/installPropsUnsafeTransition.js | 15 + packages/utils/validateProp.js | 11 + styles/Transfer.scss | 95 +++- 15 files changed, 791 insertions(+), 301 deletions(-) create mode 100644 packages/common/Checkbox/src/SimpleCheckbox.vue create mode 100644 packages/common/Transfer/src/TransferHeaderCheckbox.vue create mode 100644 packages/common/Transfer/src/TransferHeaderExtra.vue create mode 100644 packages/common/Transfer/src/TransferLightBar.vue delete mode 100644 packages/common/Transfer/src/TransferListItem.vue create mode 100644 packages/common/Transfer/src/TransferSourceListItem.vue create mode 100644 packages/common/Transfer/src/TransferTargetListItem.vue create mode 100644 packages/utils/installPropsUnsafeTransition.js create mode 100644 packages/utils/validateProp.js diff --git a/demo/documentation/components/transfer/enUS/basic.md b/demo/documentation/components/transfer/enUS/basic.md index fdf13e3b7..60c05b9af 100644 --- a/demo/documentation/components/transfer/enUS/basic.md +++ b/demo/documentation/components/transfer/enUS/basic.md @@ -11,23 +11,24 @@ Regen Values -
{{ JSON.stringify(value) }}
-
{{ $refs.transfer ? $refs.transfer._data : null }}
+ ``` ```js let prefix = null function genOptions () { prefix = Math.random().toString(36).slice(2, 5) - return Array.apply(null, { length: 20 }).map((v, i) => ({ + return Array.apply(null, { length: 1000 }).map((v, i) => ({ label: prefix + 'Option' + i, value: prefix + i, - disabled: i % 3 === 0 + disabled: i % 5 === 0 })) } function genValues () { - return Array.apply(null, { length: 5 }).map((v, i) => prefix + i) + return Array.apply(null, { length: 500 }).map((v, i) => prefix + i) } export default { diff --git a/packages/common/Checkbox/src/Checkbox.vue b/packages/common/Checkbox/src/Checkbox.vue index 5fd152830..9c23dac1a 100644 --- a/packages/common/Checkbox/src/Checkbox.vue +++ b/packages/common/Checkbox/src/Checkbox.vue @@ -58,7 +58,7 @@ export default { ], model: { prop: 'checked', - event: 'input' + event: 'change' }, props: { value: { @@ -103,8 +103,7 @@ export default { if (this.NCheckboxGroup) { this.NCheckboxGroup.toggleCheckbox(!this.synthesizedChecked, this.value) } else { - this.$emit('input', !this.synthesizedChecked) - this.$emit('change', !this.synthesizedChecked, this.value) + this.$emit('change', !this.synthesizedChecked, this.synthesizedChecked) } }, handleClick (e) { diff --git a/packages/common/Checkbox/src/SimpleCheckbox.vue b/packages/common/Checkbox/src/SimpleCheckbox.vue new file mode 100644 index 000000000..8fe8d3084 --- /dev/null +++ b/packages/common/Checkbox/src/SimpleCheckbox.vue @@ -0,0 +1,85 @@ + + + diff --git a/packages/common/Transfer/index.js b/packages/common/Transfer/index.js index 355fe3842..4725d7140 100644 --- a/packages/common/Transfer/index.js +++ b/packages/common/Transfer/index.js @@ -1,7 +1,9 @@ /* istanbul ignore file */ import Transfer from './src/Transfer.vue' +import installPropsUnsafeTransition from '../../utils/installPropsUnsafeTransition' Transfer.install = function (Vue) { + installPropsUnsafeTransition(Vue) Vue.component(Transfer.name, Transfer) } diff --git a/packages/common/Transfer/src/Transfer.vue b/packages/common/Transfer/src/Transfer.vue index 4341d6845..bc9327422 100644 --- a/packages/common/Transfer/src/Transfer.vue +++ b/packages/common/Transfer/src/Transfer.vue @@ -8,68 +8,44 @@
-
- +
Source
-
- {{ sourceCheckedValueSet.size }} / {{ sourceOptions.length }} -
+
- -
    - -
    - - +
      + + - {{ option.label }} - + />
To Target To Source @@ -78,53 +54,32 @@
- +
Target
-
- {{ targetCheckedValueSet.size }} / {{ targetOptions.length }} -
+
- -
    - -
    - - +
      + + - {{ option.label }} - + />
    @@ -133,26 +88,37 @@ diff --git a/packages/common/Transfer/src/TransferButton.vue b/packages/common/Transfer/src/TransferButton.vue index 5e7d78760..8311f5cd2 100644 --- a/packages/common/Transfer/src/TransferButton.vue +++ b/packages/common/Transfer/src/TransferButton.vue @@ -21,17 +21,27 @@ diff --git a/packages/common/Transfer/src/TransferHeaderExtra.vue b/packages/common/Transfer/src/TransferHeaderExtra.vue new file mode 100644 index 000000000..0dbf08938 --- /dev/null +++ b/packages/common/Transfer/src/TransferHeaderExtra.vue @@ -0,0 +1,32 @@ + + + diff --git a/packages/common/Transfer/src/TransferLightBar.vue b/packages/common/Transfer/src/TransferLightBar.vue new file mode 100644 index 000000000..64f1c9327 --- /dev/null +++ b/packages/common/Transfer/src/TransferLightBar.vue @@ -0,0 +1,39 @@ + + + diff --git a/packages/common/Transfer/src/TransferListItem.vue b/packages/common/Transfer/src/TransferListItem.vue deleted file mode 100644 index 6c24b294d..000000000 --- a/packages/common/Transfer/src/TransferListItem.vue +++ /dev/null @@ -1,100 +0,0 @@ - - - diff --git a/packages/common/Transfer/src/TransferSourceListItem.vue b/packages/common/Transfer/src/TransferSourceListItem.vue new file mode 100644 index 000000000..093132653 --- /dev/null +++ b/packages/common/Transfer/src/TransferSourceListItem.vue @@ -0,0 +1,104 @@ + + + diff --git a/packages/common/Transfer/src/TransferTargetListItem.vue b/packages/common/Transfer/src/TransferTargetListItem.vue new file mode 100644 index 000000000..8e48dec19 --- /dev/null +++ b/packages/common/Transfer/src/TransferTargetListItem.vue @@ -0,0 +1,104 @@ + + + diff --git a/packages/utils/installPropsUnsafeTransition.js b/packages/utils/installPropsUnsafeTransition.js new file mode 100644 index 000000000..72c255d55 --- /dev/null +++ b/packages/utils/installPropsUnsafeTransition.js @@ -0,0 +1,15 @@ +export default function (Vue) { + if (!Vue.options.components.PropsUnsafeTransition) { + const PropsUnsafeTransition = { ...(Vue.options.components.Transition) } + PropsUnsafeTransition.name = 'PropsUnsafeTransition' + PropsUnsafeTransition.props = { + name: { + validator: () => true + }, + appear: { + validator: () => true + } + } + Vue.component(PropsUnsafeTransition.name, PropsUnsafeTransition) + } +} diff --git a/packages/utils/validateProp.js b/packages/utils/validateProp.js new file mode 100644 index 000000000..b80fd0386 --- /dev/null +++ b/packages/utils/validateProp.js @@ -0,0 +1,11 @@ +function createValidator (types) { + return value => { + for (let i = 0; i < types.length; ++i) { + // eslint-disable-next-line valid-typeof + if (typeof value === types[i]) return true + } + return false + } +} + +export default createValidator diff --git a/styles/Transfer.scss b/styles/Transfer.scss index 5d7d26987..beacc9210 100644 --- a/styles/Transfer.scss +++ b/styles/Transfer.scss @@ -1,6 +1,76 @@ @import './mixins/mixins.scss'; @import './themes/vars.scss'; +@keyframes slide-in-from-left { + 0% { + max-height: 0; + transform: translateX(-100%); + } + + 50% { + max-height: 34px; + transform: translateX(-100%); + } + + 100% { + max-height: 34px; + transform: translateX(0); + } +} + +@keyframes slide-out-to-right { + 0% { + max-height: 34px; + transform: translateX(0%); + } + + 50% { + max-height: 34px; + transform: translateX(100%); + } + + 100% { + max-height: 0px; + transform: translateX(100%); + } +} + +@keyframes slide-in-from-right { + 0% { + max-height: 0; + transform: translateX(100%); + } + + 50% { + max-height: 34px; + transform: translateX(100%); + } + + 100% { + max-height: 34px; + transform: translateX(0); + } +} + +@keyframes slide-out-to-left { + 0% { + max-height: 34px; + transform: translateX(0%); + } + + 50% { + max-height: 34px; + transform: translateX(-100%); + } + + 100% { + max-height: 0px; + transform: translateX(-100%); + } +} + + + /** * There are some theme related hard codes in transfer. * Emmm, when I am writing these code I can't figure out a better solution. @@ -96,6 +166,11 @@ padding: 0; margin: 0; position: relative; + @include m(animation-disabled) { + @include b(transfer-list-item) { + animation: none !important; + } + } } @include b(transfer-list-light-bar) { @include once { @@ -109,8 +184,6 @@ } @include b(transfer-list-item) { @include once { - @include slide-right-transition(transfer-list-item-source); - @include slide-left-transition(transfer-list-item-target); transition: color .3s $--n-ease-in-out-cubic-bezier; position: relative; cursor: pointer; @@ -125,6 +198,24 @@ white-space: nowrap; padding-right: 4px; } + @include m(source) { + animation-fill-mode: forwards; + @include m(enter) { + animation: .3s slide-in-from-right; + } + @include m(leave) { + animation: .3s slide-out-to-right; + } + } + @include m(target) { + animation-fill-mode: forwards; + @include m(enter) { + animation: .3s slide-in-from-left; + } + @include m(leave) { + animation: .3s slide-out-to-left; + } + } } color: map-get($--transfer-item-text-color, 'default'); @include e(checkbox) {