refactor(ImagePreview): refactor with composition api

This commit is contained in:
chenjiahan 2020-09-14 17:36:58 +08:00
parent 32560ce3b8
commit 6ab2b3bf1f
3 changed files with 174 additions and 178 deletions

View File

@ -64,9 +64,9 @@
"devDependencies": {
"@ls-lint/ls-lint": "^1.8.0",
"@vant/cli": "^3.0.0-alpha.9",
"@vue/compiler-sfc": "3.0.0-rc.5",
"@vue/compiler-sfc": "3.0.0-rc.10",
"prettier": "^2.0.4",
"vue": "3.0.0-rc.5"
"vue": "3.0.0-rc.10"
},
"sideEffects": [
"es/**/style/*",

View File

@ -1,10 +1,12 @@
import { nextTick, onMounted, reactive, ref, watch } from 'vue';
// Utils
import { bem, createComponent } from './shared';
import { callInterceptor } from '../utils/interceptor';
// Mixins
import { TouchMixin } from '../mixins/touch';
import { BindEventMixin } from '../mixins/bind-event';
// Composition
import { useEventListener } from '@vant/use';
import { usePublicApi } from '../composition/use-public-api';
// Components
import Icon from '../icon';
@ -13,14 +15,6 @@ import Popup from '../popup';
import ImagePreviewItem from './ImagePreviewItem';
export default createComponent({
mixins: [
TouchMixin,
BindEventMixin(function (bind) {
bind(window, 'resize', this.resize, true);
bind(window, 'orientationchange', this.resize, true);
}),
],
props: {
show: Boolean,
className: null,
@ -75,153 +69,155 @@ export default createComponent({
emits: ['scale', 'close', 'closed', 'change', 'update:show'],
data() {
return {
setup(props, { emit, slots }) {
const rootRef = ref();
const swipeRef = ref();
const state = reactive({
active: 0,
rootWidth: 0,
rootHeight: 0,
doubleClickTimer: null,
});
const resize = () => {
const root = rootRef.value;
if (root && root.getBoundingClientRect) {
const rect = root.getBoundingClientRect();
state.rootWidth = rect.width;
state.rootHeight = rect.height;
}
};
},
mounted() {
this.resize();
},
const emitScale = (args) => {
emit('scale', args);
};
watch: {
startPosition: 'setActive',
show(val) {
if (val) {
this.setActive(+this.startPosition);
this.$nextTick(() => {
this.resize();
this.$refs.swipe.swipeTo(+this.startPosition, { immediate: true });
});
} else {
this.$emit('close', {
index: this.active,
url: this.images[this.active],
});
}
},
},
methods: {
resize() {
if (this.$el && this.$el.getBoundingClientRect) {
const rect = this.$el.getBoundingClientRect();
this.rootWidth = rect.width;
this.rootHeight = rect.height;
}
},
emitClose() {
const emitClose = () => {
callInterceptor({
interceptor: this.beforeClose,
args: [this.active],
interceptor: props.beforeClose,
args: [state.active],
done: () => {
this.$emit('update:show', false);
emit('update:show', false);
},
});
},
};
emitScale(args) {
this.$emit('scale', args);
},
setActive(active) {
if (active !== this.active) {
this.active = active;
this.$emit('change', active);
const setActive = (active) => {
if (active !== state.active) {
state.active = active;
emit('change', active);
}
},
};
genIndex() {
if (this.showIndex) {
const renderIndex = () => {
if (props.showIndex) {
return (
<div class={bem('index')}>
{this.$slots.index
? this.$slots.index()
: `${this.active + 1} / ${this.images.length}`}
{slots.index
? slots.index()
: `${state.active + 1} / ${props.images.length}`}
</div>
);
}
},
};
genCover() {
if (this.$slots.cover) {
return <div class={bem('cover')}>{this.$slots.cover()}</div>;
const renderCover = () => {
if (slots.cover) {
return <div class={bem('cover')}>{slots.cover()}</div>;
}
},
};
genImages() {
return (
<Swipe
ref="swipe"
lazyRender
loop={this.loop}
class={bem('swipe')}
duration={this.swipeDuration}
initialSwipe={this.startPosition}
showIndicators={this.showIndicators}
indicatorColor="white"
onChange={this.setActive}
>
{this.images.map((image) => (
<ImagePreviewItem
src={image}
show={this.show}
active={this.active}
maxZoom={this.maxZoom}
minZoom={this.minZoom}
rootWidth={this.rootWidth}
rootHeight={this.rootHeight}
onScale={this.emitScale}
onClose={this.emitClose}
/>
))}
</Swipe>
);
},
const renderImages = () => (
<Swipe
ref={swipeRef}
lazyRender
loop={props.loop}
class={bem('swipe')}
duration={props.swipeDuration}
initialSwipe={props.startPosition}
showIndicators={props.showIndicators}
indicatorColor="white"
onChange={setActive}
>
{props.images.map((image) => (
<ImagePreviewItem
src={image}
show={props.show}
active={state.active}
maxZoom={props.maxZoom}
minZoom={props.minZoom}
rootWidth={state.rootWidth}
rootHeight={state.rootHeight}
onScale={emitScale}
onClose={emitClose}
/>
))}
</Swipe>
);
genClose() {
if (this.closeable) {
const renderClose = () => {
if (props.closeable) {
return (
<Icon
role="button"
name={this.closeIcon}
class={bem('close-icon', this.closeIconPosition)}
onClick={this.emitClose}
name={props.closeIcon}
class={bem('close-icon', props.closeIconPosition)}
onClick={emitClose}
/>
);
}
},
};
onClosed() {
this.$emit('closed');
},
const onClosed = () => {
emit('closed');
};
// @exposed-api
swipeTo(index, options) {
if (this.$refs.swipe) {
this.$refs.swipe.swipeTo(index, options);
const swipeTo = (index, options) => {
if (swipeRef.value) {
swipeRef.value.swipeTo(index, options);
}
},
},
};
render() {
return (
usePublicApi({ swipeTo });
useEventListener('resize', resize);
useEventListener('orientationchange', resize);
onMounted(resize);
watch(() => props.startPosition, setActive);
watch(
() => props.show,
(value) => {
const { images, startPosition } = props;
if (value) {
setActive(+startPosition);
nextTick(() => {
resize();
swipeRef.value.swipeTo(+startPosition, { immediate: true });
});
} else {
emit('close', {
index: state.active,
url: images[state.active],
});
}
}
);
return () => (
<Popup
show={this.show}
class={[bem(), this.className]}
ref={rootRef}
show={props.show}
class={[bem(), props.className]}
overlayClass={bem('overlay')}
onClosed={this.onClosed}
closeOnPopstate={props.closeOnPopstate}
onClosed={onClosed}
>
{this.genClose()}
{this.genImages()}
{this.genIndex()}
{this.genCover()}
{renderClose()}
{renderImages()}
{renderIndex()}
{renderCover()}
</Popup>
);
},

106
yarn.lock
View File

@ -2180,36 +2180,36 @@
html-tags "^3.1.0"
svg-tags "^1.0.0"
"@vue/compiler-core@3.0.0-rc.5":
version "3.0.0-rc.5"
resolved "https://registry.npm.taobao.org/@vue/compiler-core/download/@vue/compiler-core-3.0.0-rc.5.tgz?cache=0&sync_timestamp=1599065111625&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcompiler-core%2Fdownload%2F%40vue%2Fcompiler-core-3.0.0-rc.5.tgz#dd4f1816fcae34a81bc60e584f97993cad284d54"
integrity sha1-3U8YFvyuNKgbxg5YT5eZPK0oTVQ=
"@vue/compiler-core@3.0.0-rc.10":
version "3.0.0-rc.10"
resolved "https://registry.npm.taobao.org/@vue/compiler-core/download/@vue/compiler-core-3.0.0-rc.10.tgz?cache=0&sync_timestamp=1599065111625&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcompiler-core%2Fdownload%2F%40vue%2Fcompiler-core-3.0.0-rc.10.tgz#a76f713fb0462429ec0ec10a472fff1f539c5772"
integrity sha1-p29xP7BGJCnsDsEKRy//H1OcV3I=
dependencies:
"@babel/parser" "^7.10.4"
"@babel/types" "^7.10.4"
"@vue/shared" "3.0.0-rc.5"
"@vue/shared" "3.0.0-rc.10"
estree-walker "^2.0.1"
source-map "^0.6.1"
"@vue/compiler-dom@3.0.0-rc.5":
version "3.0.0-rc.5"
resolved "https://registry.npm.taobao.org/@vue/compiler-dom/download/@vue/compiler-dom-3.0.0-rc.5.tgz?cache=0&sync_timestamp=1599065111635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcompiler-dom%2Fdownload%2F%40vue%2Fcompiler-dom-3.0.0-rc.5.tgz#83905e8601123a3654b90fbd80708a16530ce21a"
integrity sha1-g5BehgESOjZUuQ+9gHCKFlMM4ho=
"@vue/compiler-dom@3.0.0-rc.10":
version "3.0.0-rc.10"
resolved "https://registry.npm.taobao.org/@vue/compiler-dom/download/@vue/compiler-dom-3.0.0-rc.10.tgz?cache=0&sync_timestamp=1599065111635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcompiler-dom%2Fdownload%2F%40vue%2Fcompiler-dom-3.0.0-rc.10.tgz#dd1380d1ee61170de76f9eb91e0d8ac7985f0ae0"
integrity sha1-3ROA0e5hFw3nb565Hg2Kx5hfCuA=
dependencies:
"@vue/compiler-core" "3.0.0-rc.5"
"@vue/shared" "3.0.0-rc.5"
"@vue/compiler-core" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
"@vue/compiler-sfc@3.0.0-rc.5":
version "3.0.0-rc.5"
resolved "https://registry.npm.taobao.org/@vue/compiler-sfc/download/@vue/compiler-sfc-3.0.0-rc.5.tgz#374e52a6fbf8fb9aee1213026050a0f1c496fecf"
integrity sha1-N05Spvv4+5ruEhMCYFCg8cSW/s8=
"@vue/compiler-sfc@3.0.0-rc.10":
version "3.0.0-rc.10"
resolved "https://registry.npm.taobao.org/@vue/compiler-sfc/download/@vue/compiler-sfc-3.0.0-rc.10.tgz?cache=0&sync_timestamp=1599065111795&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcompiler-sfc%2Fdownload%2F%40vue%2Fcompiler-sfc-3.0.0-rc.10.tgz#4351ece66cdf4d758877482f69421c43d994dbaf"
integrity sha1-Q1Hs5mzfTXWId0gvaUIcQ9mU268=
dependencies:
"@babel/parser" "^7.10.4"
"@babel/types" "^7.10.4"
"@vue/compiler-core" "3.0.0-rc.5"
"@vue/compiler-dom" "3.0.0-rc.5"
"@vue/compiler-ssr" "3.0.0-rc.5"
"@vue/shared" "3.0.0-rc.5"
"@vue/compiler-core" "3.0.0-rc.10"
"@vue/compiler-dom" "3.0.0-rc.10"
"@vue/compiler-ssr" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
consolidate "^0.15.1"
estree-walker "^2.0.1"
hash-sum "^2.0.0"
@ -2221,13 +2221,13 @@
postcss-selector-parser "^6.0.2"
source-map "^0.6.1"
"@vue/compiler-ssr@3.0.0-rc.5":
version "3.0.0-rc.5"
resolved "https://registry.npm.taobao.org/@vue/compiler-ssr/download/@vue/compiler-ssr-3.0.0-rc.5.tgz?cache=0&sync_timestamp=1599065111870&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcompiler-ssr%2Fdownload%2F%40vue%2Fcompiler-ssr-3.0.0-rc.5.tgz#878406c59daff362ecdcb199fb9467a769ca8de5"
integrity sha1-h4QGxZ2v82Ls3LGZ+5Rnp2nKjeU=
"@vue/compiler-ssr@3.0.0-rc.10":
version "3.0.0-rc.10"
resolved "https://registry.npm.taobao.org/@vue/compiler-ssr/download/@vue/compiler-ssr-3.0.0-rc.10.tgz?cache=0&sync_timestamp=1599065111870&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcompiler-ssr%2Fdownload%2F%40vue%2Fcompiler-ssr-3.0.0-rc.10.tgz#95a5f6b65b19a514c94f056994ec144b3b1b03ae"
integrity sha1-laX2tlsZpRTJTwVplOwUSzsbA64=
dependencies:
"@vue/compiler-dom" "3.0.0-rc.5"
"@vue/shared" "3.0.0-rc.5"
"@vue/compiler-dom" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
"@vue/component-compiler-utils@^3.1.2":
version "3.1.2"
@ -2245,34 +2245,34 @@
optionalDependencies:
prettier "^1.18.2"
"@vue/reactivity@3.0.0-rc.5":
version "3.0.0-rc.5"
resolved "https://registry.npm.taobao.org/@vue/reactivity/download/@vue/reactivity-3.0.0-rc.5.tgz?cache=0&sync_timestamp=1599065204064&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Freactivity%2Fdownload%2F%40vue%2Freactivity-3.0.0-rc.5.tgz#45cff8d839d7ad130b1e499239090050fdecff13"
integrity sha1-Rc/42DnXrRMLHkmSOQkAUP3s/xM=
"@vue/reactivity@3.0.0-rc.10":
version "3.0.0-rc.10"
resolved "https://registry.npm.taobao.org/@vue/reactivity/download/@vue/reactivity-3.0.0-rc.10.tgz?cache=0&sync_timestamp=1599065204064&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Freactivity%2Fdownload%2F%40vue%2Freactivity-3.0.0-rc.10.tgz#34d5f51bcc5a7c36e27d7a9c1bd7a3d25ffa7c56"
integrity sha1-NNX1G8xafDbifXqcG9ej0l/6fFY=
dependencies:
"@vue/shared" "3.0.0-rc.5"
"@vue/shared" "3.0.0-rc.10"
"@vue/runtime-core@3.0.0-rc.5":
version "3.0.0-rc.5"
resolved "https://registry.npm.taobao.org/@vue/runtime-core/download/@vue/runtime-core-3.0.0-rc.5.tgz?cache=0&sync_timestamp=1599065204365&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fruntime-core%2Fdownload%2F%40vue%2Fruntime-core-3.0.0-rc.5.tgz#dd59af3a5fc089d1cdc05a657320c0dc17e5c362"
integrity sha1-3VmvOl/AidHNwFplcyDA3Bflw2I=
"@vue/runtime-core@3.0.0-rc.10":
version "3.0.0-rc.10"
resolved "https://registry.npm.taobao.org/@vue/runtime-core/download/@vue/runtime-core-3.0.0-rc.10.tgz?cache=0&sync_timestamp=1599065204365&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fruntime-core%2Fdownload%2F%40vue%2Fruntime-core-3.0.0-rc.10.tgz#9055aef5113cbc328aaec29760c2151e0ed3cf40"
integrity sha1-kFWu9RE8vDKKrsKXYMIVHg7Tz0A=
dependencies:
"@vue/reactivity" "3.0.0-rc.5"
"@vue/shared" "3.0.0-rc.5"
"@vue/reactivity" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
"@vue/runtime-dom@3.0.0-rc.5":
version "3.0.0-rc.5"
resolved "https://registry.npm.taobao.org/@vue/runtime-dom/download/@vue/runtime-dom-3.0.0-rc.5.tgz?cache=0&sync_timestamp=1599065204677&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fruntime-dom%2Fdownload%2F%40vue%2Fruntime-dom-3.0.0-rc.5.tgz#2fd75a1f29b23abf0ffe5ccdedabda11721c5b5b"
integrity sha1-L9daHymyOr8P/lzN7avaEXIcW1s=
"@vue/runtime-dom@3.0.0-rc.10":
version "3.0.0-rc.10"
resolved "https://registry.npm.taobao.org/@vue/runtime-dom/download/@vue/runtime-dom-3.0.0-rc.10.tgz?cache=0&sync_timestamp=1599065204677&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fruntime-dom%2Fdownload%2F%40vue%2Fruntime-dom-3.0.0-rc.10.tgz#50f95cb991483a4262163723320967ad17bb321f"
integrity sha1-UPlcuZFIOkJiFjcjMglnrRe7Mh8=
dependencies:
"@vue/runtime-core" "3.0.0-rc.5"
"@vue/shared" "3.0.0-rc.5"
"@vue/runtime-core" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
csstype "^2.6.8"
"@vue/shared@3.0.0-rc.5":
version "3.0.0-rc.5"
resolved "https://registry.npm.taobao.org/@vue/shared/download/@vue/shared-3.0.0-rc.5.tgz?cache=0&sync_timestamp=1599065113122&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fshared%2Fdownload%2F%40vue%2Fshared-3.0.0-rc.5.tgz#cea2378e3e37363ddc1f5dd158edc9c9b5b3fff0"
integrity sha1-zqI3jj43Nj3cH13RWO3JybWz//A=
"@vue/shared@3.0.0-rc.10":
version "3.0.0-rc.10"
resolved "https://registry.npm.taobao.org/@vue/shared/download/@vue/shared-3.0.0-rc.10.tgz?cache=0&sync_timestamp=1599065113122&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fshared%2Fdownload%2F%40vue%2Fshared-3.0.0-rc.10.tgz#e7ab62abcabbfc738545902b96a3aa78f59f3286"
integrity sha1-56tiq8q7/HOFRZArlqOqePWfMoY=
"@vue/test-utils@2.0.0-beta.2":
version "2.0.0-beta.2"
@ -12458,14 +12458,14 @@ vue-template-es2015-compiler@^1.9.0:
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
vue@3.0.0-rc.5:
version "3.0.0-rc.5"
resolved "https://registry.npm.taobao.org/vue/download/vue-3.0.0-rc.5.tgz#973175d45a892b3bd23ef5de7faa4add9c66275f"
integrity sha1-lzF11FqJKzvSPvXef6pK3ZxmJ18=
vue@3.0.0-rc.10:
version "3.0.0-rc.10"
resolved "https://registry.npm.taobao.org/vue/download/vue-3.0.0-rc.10.tgz#31298a757b4fad6ee8973d0fa27c4fde8574bd01"
integrity sha1-MSmKdXtPrW7olz0PonxP3oV0vQE=
dependencies:
"@vue/compiler-dom" "3.0.0-rc.5"
"@vue/runtime-dom" "3.0.0-rc.5"
"@vue/shared" "3.0.0-rc.5"
"@vue/compiler-dom" "3.0.0-rc.10"
"@vue/runtime-dom" "3.0.0-rc.10"
"@vue/shared" "3.0.0-rc.10"
w3c-hr-time@^1.0.1:
version "1.0.2"