234 lines
5.4 KiB
JavaScript
234 lines
5.4 KiB
JavaScript
![]() |
// 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 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);
|
||
|
})],
|
||
|
props: {
|
||
|
className: null,
|
||
|
closeable: Boolean,
|
||
|
asyncClose: Boolean,
|
||
|
overlayStyle: Object,
|
||
|
showIndicators: Boolean,
|
||
|
images: {
|
||
|
type: Array,
|
||
|
default: function _default() {
|
||
|
return [];
|
||
|
}
|
||
|
},
|
||
|
loop: {
|
||
|
type: Boolean,
|
||
|
default: true
|
||
|
},
|
||
|
overlay: {
|
||
|
type: Boolean,
|
||
|
default: true
|
||
|
},
|
||
|
minZoom: {
|
||
|
type: [Number, String],
|
||
|
default: 1 / 3
|
||
|
},
|
||
|
maxZoom: {
|
||
|
type: [Number, String],
|
||
|
default: 3
|
||
|
},
|
||
|
transition: {
|
||
|
type: String,
|
||
|
default: 'van-fade'
|
||
|
},
|
||
|
showIndex: {
|
||
|
type: Boolean,
|
||
|
default: true
|
||
|
},
|
||
|
swipeDuration: {
|
||
|
type: [Number, String],
|
||
|
default: 300
|
||
|
},
|
||
|
startPosition: {
|
||
|
type: [Number, String],
|
||
|
default: 0
|
||
|
},
|
||
|
overlayClass: {
|
||
|
type: String,
|
||
|
default: bem('overlay')
|
||
|
},
|
||
|
closeIcon: {
|
||
|
type: String,
|
||
|
default: 'clear'
|
||
|
},
|
||
|
closeOnPopstate: {
|
||
|
type: Boolean,
|
||
|
default: true
|
||
|
},
|
||
|
closeIconPosition: {
|
||
|
type: String,
|
||
|
default: 'top-right'
|
||
|
}
|
||
|
},
|
||
|
data: function data() {
|
||
|
return {
|
||
|
active: 0,
|
||
|
rootWidth: 0,
|
||
|
rootHeight: 0,
|
||
|
doubleClickTimer: null
|
||
|
};
|
||
|
},
|
||
|
mounted: function mounted() {
|
||
|
this.resize();
|
||
|
},
|
||
|
watch: {
|
||
|
startPosition: 'setActive',
|
||
|
value: function value(val) {
|
||
|
var _this = this;
|
||
|
|
||
|
if (val) {
|
||
|
this.setActive(+this.startPosition);
|
||
|
this.$nextTick(function () {
|
||
|
_this.resize();
|
||
|
|
||
|
_this.$refs.swipe.swipeTo(+_this.startPosition, {
|
||
|
immediate: true
|
||
|
});
|
||
|
});
|
||
|
} else {
|
||
|
this.$emit('close', {
|
||
|
index: this.active,
|
||
|
url: this.images[this.active]
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
methods: {
|
||
|
resize: function resize() {
|
||
|
if (this.$el && this.$el.getBoundingClientRect) {
|
||
|
var rect = this.$el.getBoundingClientRect();
|
||
|
this.rootWidth = rect.width;
|
||
|
this.rootHeight = rect.height;
|
||
|
}
|
||
|
},
|
||
|
emitClose: function emitClose() {
|
||
|
if (!this.asyncClose) {
|
||
|
this.$emit('input', false);
|
||
|
}
|
||
|
},
|
||
|
emitScale: function emitScale(args) {
|
||
|
this.$emit('scale', args);
|
||
|
},
|
||
|
setActive: function setActive(active) {
|
||
|
if (active !== this.active) {
|
||
|
this.active = active;
|
||
|
this.$emit('change', active);
|
||
|
}
|
||
|
},
|
||
|
genIndex: function genIndex() {
|
||
|
var h = this.$createElement;
|
||
|
|
||
|
if (this.showIndex) {
|
||
|
return h("div", {
|
||
|
"class": bem('index')
|
||
|
}, [this.slots('index', {
|
||
|
index: this.active
|
||
|
}) || this.active + 1 + " / " + this.images.length]);
|
||
|
}
|
||
|
},
|
||
|
genCover: function genCover() {
|
||
|
var h = this.$createElement;
|
||
|
var cover = this.slots('cover');
|
||
|
|
||
|
if (cover) {
|
||
|
return h("div", {
|
||
|
"class": bem('cover')
|
||
|
}, [cover]);
|
||
|
}
|
||
|
},
|
||
|
genImages: function genImages() {
|
||
|
var _this2 = this;
|
||
|
|
||
|
var h = this.$createElement;
|
||
|
return h(Swipe, {
|
||
|
"ref": "swipe",
|
||
|
"attrs": {
|
||
|
"lazyRender": true,
|
||
|
"loop": this.loop,
|
||
|
"duration": this.swipeDuration,
|
||
|
"initialSwipe": this.startPosition,
|
||
|
"showIndicators": this.showIndicators,
|
||
|
"indicatorColor": "white"
|
||
|
},
|
||
|
"class": bem('swipe'),
|
||
|
"on": {
|
||
|
"change": this.setActive
|
||
|
}
|
||
|
}, [this.images.map(function (image) {
|
||
|
return h(ImagePreviewItem, {
|
||
|
"attrs": {
|
||
|
"src": image,
|
||
|
"show": _this2.value,
|
||
|
"active": _this2.active,
|
||
|
"maxZoom": _this2.maxZoom,
|
||
|
"minZoom": _this2.minZoom,
|
||
|
"rootWidth": _this2.rootWidth,
|
||
|
"rootHeight": _this2.rootHeight
|
||
|
},
|
||
|
"on": {
|
||
|
"scale": _this2.emitScale,
|
||
|
"close": _this2.emitClose
|
||
|
}
|
||
|
});
|
||
|
})]);
|
||
|
},
|
||
|
genClose: function genClose() {
|
||
|
var h = this.$createElement;
|
||
|
|
||
|
if (this.closeable) {
|
||
|
return h(Icon, {
|
||
|
"attrs": {
|
||
|
"role": "button",
|
||
|
"name": this.closeIcon
|
||
|
},
|
||
|
"class": bem('close-icon', this.closeIconPosition),
|
||
|
"on": {
|
||
|
"click": this.emitClose
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
onClosed: function onClosed() {
|
||
|
this.$emit('closed');
|
||
|
},
|
||
|
// @exposed-api
|
||
|
swipeTo: function swipeTo(index, options) {
|
||
|
if (this.$refs.swipe) {
|
||
|
this.$refs.swipe.swipeTo(index, options);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
render: function render() {
|
||
|
var h = arguments[0];
|
||
|
return h("transition", {
|
||
|
"attrs": {
|
||
|
"name": this.transition
|
||
|
},
|
||
|
"on": {
|
||
|
"afterLeave": this.onClosed
|
||
|
}
|
||
|
}, [this.shouldRender ? h("div", {
|
||
|
"directives": [{
|
||
|
name: "show",
|
||
|
value: this.value
|
||
|
}],
|
||
|
"class": [bem(), this.className]
|
||
|
}, [this.genClose(), this.genImages(), this.genIndex(), this.genCover()]) : null]);
|
||
|
}
|
||
|
});
|