You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
5.4 KiB
234 lines
5.4 KiB
// 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,
|
|
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
|
|
},
|
|
showIndex: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
swipeDuration: {
|
|
type: [Number, String],
|
|
default: 500
|
|
},
|
|
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];
|
|
|
|
if (!this.shouldRender) {
|
|
return;
|
|
}
|
|
|
|
return h("transition", {
|
|
"attrs": {
|
|
"name": "van-fade"
|
|
},
|
|
"on": {
|
|
"afterLeave": this.onClosed
|
|
}
|
|
}, [h("div", {
|
|
"directives": [{
|
|
name: "show",
|
|
value: this.value
|
|
}],
|
|
"class": [bem(), this.className]
|
|
}, [this.genClose(), this.genImages(), this.genIndex(), this.genCover()])]);
|
|
}
|
|
}); |