From 3a290ce5649812570c4a2450acbbfd03eff9f782 Mon Sep 17 00:00:00 2001 From: chenjiahan Date: Mon, 17 Aug 2020 10:38:11 +0800 Subject: [PATCH] feat: migrate ImagePreview component --- components.js | 1 + src/image-preview/ImagePreview.js | 52 +++++++------- src/image-preview/ImagePreviewItem.js | 4 +- src/image-preview/index.js | 98 ++++++++++++++++++--------- src/image-preview/index.less | 2 + src/mixins/relation.js | 2 +- vant.config.js | 16 ++--- 7 files changed, 104 insertions(+), 71 deletions(-) diff --git a/components.js b/components.js index ae9960b70..f276ceefd 100644 --- a/components.js +++ b/components.js @@ -64,4 +64,5 @@ module.exports = [ 'collapse-item', 'swipe', 'swipe-item', + 'image-preview', ]; diff --git a/src/image-preview/ImagePreview.js b/src/image-preview/ImagePreview.js index 3b56ee72e..7325560f0 100644 --- a/src/image-preview/ImagePreview.js +++ b/src/image-preview/ImagePreview.js @@ -3,21 +3,18 @@ import { inBrowser } from '../utils'; import { bem, createComponent } from './shared'; // Mixins -import { PopupMixin } from '../mixins/popup'; import { TouchMixin } from '../mixins/touch'; import { BindEventMixin } from '../mixins/bind-event'; // Components import Icon from '../icon'; import Swipe from '../swipe'; +import Popup from '../popup'; import ImagePreviewItem from './ImagePreviewItem'; export default createComponent({ mixins: [ TouchMixin, - PopupMixin({ - skipToggleEvent: true, - }), BindEventMixin(function (bind) { bind(window, 'resize', this.resize, true); bind(window, 'orientationchange', this.resize, true); @@ -25,6 +22,7 @@ export default createComponent({ ], props: { + show: Boolean, className: null, closeable: Boolean, asyncClose: Boolean, @@ -61,10 +59,6 @@ export default createComponent({ type: [Number, String], default: 0, }, - overlayClass: { - type: String, - default: bem('overlay'), - }, closeIcon: { type: String, default: 'clear', @@ -79,6 +73,8 @@ export default createComponent({ }, }, + emits: ['scale', 'close', 'closed', 'change', 'update:show'], + data() { return { active: 0, @@ -95,7 +91,7 @@ export default createComponent({ watch: { startPosition: 'setActive', - value(val) { + show(val) { if (val) { this.setActive(+this.startPosition); this.$nextTick(() => { @@ -120,7 +116,7 @@ export default createComponent({ emitClose() { if (!this.asyncClose) { - this.$emit('input', false); + this.$emit('update:show', false); } }, @@ -139,18 +135,17 @@ export default createComponent({ if (this.showIndex) { return (
- {this.slots('index') || - `${this.active + 1} / ${this.images.length}`} + {this.$slots.index + ? this.$slots.index() + : `${this.active + 1} / ${this.images.length}`}
); } }, genCover() { - const cover = this.slots('cover'); - - if (cover) { - return
{cover}
; + if (this.$slots.cover) { + return
{this.$slots.cover()}
; } }, @@ -170,7 +165,7 @@ export default createComponent({ {this.images.map((image) => ( -
- {this.genClose()} - {this.genImages()} - {this.genIndex()} - {this.genCover()} -
- + + {this.genClose()} + {this.genImages()} + {this.genIndex()} + {this.genCover()} + ); }, }); diff --git a/src/image-preview/ImagePreviewItem.js b/src/image-preview/ImagePreviewItem.js index 0c4c2ec0d..7285f5a9a 100644 --- a/src/image-preview/ImagePreviewItem.js +++ b/src/image-preview/ImagePreviewItem.js @@ -31,6 +31,8 @@ export default { windowHeight: Number, }, + emits: ['scale', 'close'], + data() { return { scale: 1, @@ -250,11 +252,11 @@ export default { return ( diff --git a/src/image-preview/index.js b/src/image-preview/index.js index 5bc02398f..a62ecf767 100644 --- a/src/image-preview/index.js +++ b/src/image-preview/index.js @@ -1,15 +1,15 @@ -// import Vue from 'vue'; -import VueImagePreview from './ImagePreview'; +import { createApp, nextTick } from 'vue'; +import VanImagePreview from './ImagePreview'; import { inBrowser } from '../utils'; let instance; const defaultConfig = { loop: true, - value: true, images: [], maxZoom: 3, minZoom: 1 / 3, + onScale: null, onClose: null, onChange: null, className: '', @@ -25,24 +25,59 @@ const defaultConfig = { closeIconPosition: 'top-right', }; -const initInstance = () => { - instance = new (Vue.extend(VueImagePreview))({ - el: document.createElement('div'), - }); - document.body.appendChild(instance.$el); +function initInstance() { + const root = document.createElement('div'); + document.body.appendChild(root); - instance.$on('change', (index) => { - if (instance.onChange) { - instance.onChange(index); - } - }); + instance = createApp({ + data() { + return { + props: { + show: false, + }, + }; + }, + methods: { + close() { + this.toggle(false); + }, + toggle(show) { + this.props.show = show; + }, + setProps(props) { + Object.assign(this.props, props); + }, + onClosed() { + this.props.images = []; + }, + }, + render() { + return ( + + ); + }, + }).mount(root); +} - instance.$on('scale', (data) => { - if (instance.onScale) { - instance.onScale(data); - } - }); -}; +// const initInstance = () => { +// instance.$on('change', (index) => { +// if (instance.onChange) { +// instance.onChange(index); +// } +// }); + +// instance.$on('scale', (data) => { +// if (instance.onScale) { +// instance.onScale(data); +// } +// }); +// }; const ImagePreview = (images, startPosition = 0) => { /* istanbul ignore if */ @@ -56,28 +91,27 @@ const ImagePreview = (images, startPosition = 0) => { const options = Array.isArray(images) ? { images, startPosition } : images; - Object.assign(instance, defaultConfig, options); - - instance.$once('input', (show) => { - instance.value = show; + instance.setProps({ + ...defaultConfig, + ...options, }); - instance.$once('closed', () => { - instance.images = []; + nextTick(() => { + instance.toggle(true); }); - if (options.onClose) { - instance.$off('close'); - instance.$once('close', options.onClose); - } + // if (options.onClose) { + // instance.$off('close'); + // instance.$once('close', options.onClose); + // } return instance; }; -ImagePreview.Component = VueImagePreview; +ImagePreview.Component = VanImagePreview; -ImagePreview.install = () => { - Vue.use(VueImagePreview); +ImagePreview.install = (app) => { + app.use(VanImagePreview); }; export default ImagePreview; diff --git a/src/image-preview/index.less b/src/image-preview/index.less index adf1433d2..a8b748624 100644 --- a/src/image-preview/index.less +++ b/src/image-preview/index.less @@ -6,6 +6,8 @@ left: 0; width: 100%; height: 100%; + background-color: transparent; + transform: none; &__swipe { height: 100%; diff --git a/src/mixins/relation.js b/src/mixins/relation.js index 0e65df6b3..a0bced13b 100644 --- a/src/mixins/relation.js +++ b/src/mixins/relation.js @@ -26,7 +26,7 @@ export function ChildrenMixin(parent, options = {}) { this.bindRelation(); }, - beforeDestroy() { + beforeUnmount() { if (this.parent) { this.parent.children = this.parent.children.filter( (item) => item !== this diff --git a/vant.config.js b/vant.config.js index 5e7cc0fc1..12faec808 100644 --- a/vant.config.js +++ b/vant.config.js @@ -241,10 +241,10 @@ module.exports = { path: 'empty', title: 'Empty 空状态', }, - // { - // path: 'image-preview', - // title: 'ImagePreview 图片预览', - // }, + { + path: 'image-preview', + title: 'ImagePreview 图片预览', + }, // { // path: 'lazyload', // title: 'Lazyload 懒加载', @@ -575,10 +575,10 @@ module.exports = { path: 'empty', title: 'Empty', }, - // { - // path: 'image-preview', - // title: 'ImagePreview', - // }, + { + path: 'image-preview', + title: 'ImagePreview', + }, // { // path: 'lazyload', // title: 'Lazyload',