mall-uniapp/sheep/ui/su-image/su-image.vue

131 lines
2.7 KiB
Vue

<template>
<image
v-if="!state.isError"
class="su-img"
:style="customStyle"
:draggable="false"
:mode="mode"
:src="sheep.$url.cdn(src)"
@tap="onImgPreview"
@load="onImgLoad"
@error="onImgError"
></image>
</template>
<script setup>
/**
* 图片组件
*
* @property {String} src - 图片地址
* @property {Number} mode - 裁剪方式
* @property {String} isPreview - 是否开启预览
* @property {Number} previewList - 预览列表
* @property {String} current - 预览首张下标
*
* @event {Function} load - 图片加载完毕触发
* @event {Function} error - 图片加载错误触发
*
*/
import { reactive, computed } from 'vue';
import sheep from '@/sheep';
// 组件数据
const state = reactive({
isError: false,
imgHeight: 600,
});
// 接收参数
const props = defineProps({
src: {
type: String,
default: '',
},
errorSrc: {
type: String,
default: '/static/img/shop/empty_network.png',
},
mode: {
type: String,
default: 'widthFix',
},
isPreview: {
type: Boolean,
default: false,
},
previewList: {
type: Array,
default() {
return [];
},
},
current: {
type: Number,
default: -1,
},
height: {
type: Number,
default: 0,
},
width: {
type: Number,
default: 0,
},
radius: {
type: Number,
default: 0,
},
});
const emits = defineEmits(['load', 'error']);
const customStyle = computed(() => {
return {
height: (props.height || state.imgHeight) + 'rpx',
width: props.width ? props.width + 'rpx' : '100%',
borderRadius: props.radius ? props.radius + 'rpx' : '',
};
});
// 图片加载完成
function onImgLoad(e) {
if (props.height === 0) {
state.imgHeight = (e.detail.height / e.detail.width) * 750;
}
}
// 图片加载错误
function onImgError(e) {
state.isError = true;
emits('error', e);
}
// 预览图片
function onImgPreview() {
if (!props.isPreview) return;
uni.previewImage({
urls: props.previewList.length < 1 ? [props.src] : props.previewList,
current: props.current,
longPressActions: {
itemList: ['发送给朋友', '保存图片', '收藏'],
success: function (data) {
console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
},
fail: function (err) {
console.log(err.errMsg);
},
},
});
}
</script>
<style lang="scss" scoped>
.su-img {
position: relative;
width: 100%;
height: 100%;
display: block;
}
</style>