mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-21 22:09:16 +08:00
feat: migrate ImagePreview component
This commit is contained in:
parent
b4e02668cf
commit
3a290ce564
@ -64,4 +64,5 @@ module.exports = [
|
||||
'collapse-item',
|
||||
'swipe',
|
||||
'swipe-item',
|
||||
'image-preview',
|
||||
];
|
||||
|
@ -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 (
|
||||
<div class={bem('index')}>
|
||||
{this.slots('index') ||
|
||||
`${this.active + 1} / ${this.images.length}`}
|
||||
{this.$slots.index
|
||||
? this.$slots.index()
|
||||
: `${this.active + 1} / ${this.images.length}`}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
genCover() {
|
||||
const cover = this.slots('cover');
|
||||
|
||||
if (cover) {
|
||||
return <div class={bem('cover')}>{cover}</div>;
|
||||
if (this.$slots.cover) {
|
||||
return <div class={bem('cover')}>{this.$slots.cover()}</div>;
|
||||
}
|
||||
},
|
||||
|
||||
@ -170,7 +165,7 @@ export default createComponent({
|
||||
{this.images.map((image) => (
|
||||
<ImagePreviewItem
|
||||
src={image}
|
||||
show={this.value}
|
||||
show={this.show}
|
||||
active={this.active}
|
||||
maxZoom={this.maxZoom}
|
||||
minZoom={this.minZoom}
|
||||
@ -210,19 +205,18 @@ export default createComponent({
|
||||
},
|
||||
|
||||
render() {
|
||||
if (!this.shouldRender) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
<transition name="van-fade" onAfterLeave={this.onClosed}>
|
||||
<div vShow={this.value} class={[bem(), this.className]}>
|
||||
<Popup
|
||||
show={this.show}
|
||||
class={[bem(), this.className]}
|
||||
overlayClass={bem('overlay')}
|
||||
onClosed={this.onClosed}
|
||||
>
|
||||
{this.genClose()}
|
||||
{this.genImages()}
|
||||
{this.genIndex()}
|
||||
{this.genCover()}
|
||||
</div>
|
||||
</transition>
|
||||
</Popup>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
@ -31,6 +31,8 @@ export default {
|
||||
windowHeight: Number,
|
||||
},
|
||||
|
||||
emits: ['scale', 'close'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
scale: 1,
|
||||
@ -250,11 +252,11 @@ export default {
|
||||
return (
|
||||
<SwipeItem class={bem('swipe-item')}>
|
||||
<Image
|
||||
v-slots={imageSlots}
|
||||
src={this.src}
|
||||
fit="contain"
|
||||
class={bem('image', { vertical: this.vertical })}
|
||||
style={this.imageStyle}
|
||||
scopedSlots={imageSlots}
|
||||
onLoad={this.onLoad}
|
||||
/>
|
||||
</SwipeItem>
|
||||
|
@ -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.$on('scale', (data) => {
|
||||
if (instance.onScale) {
|
||||
instance.onScale(data);
|
||||
}
|
||||
});
|
||||
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 (
|
||||
<VanImagePreview
|
||||
{...{
|
||||
...this.props,
|
||||
onClosed: this.onClosed,
|
||||
'onUpdate:show': this.toggle,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
}).mount(root);
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
@ -6,6 +6,8 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: transparent;
|
||||
transform: none;
|
||||
|
||||
&__swipe {
|
||||
height: 100%;
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
|
Loading…
x
Reference in New Issue
Block a user