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>
 |