131 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			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>
 |