You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
4.6 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view @click="click" class="tm-images overflow fulled " :class="[round=='rounded'?'rounded':`round-${round}`]">
<view class="fulled fulled-height tm-images-load flex-center">
<view class="d-inline-block load">
<text v-if="isLoad" class="iconfont icon-loading text-size-n text-grey"></text>
</view>
<view class="d-inline-block" v-if="isError">
<slot name="error">
<text class="iconfont icon-exclamationcircle-f text-size-xl text-grey-lighten-2"></text>
</slot>
</view>
<image v-show="!isLoad" @error="error"
:class="[round=='rounded'?'rounded':`round-${round}`]"
:style="{
width:w+'px',
height:h+'px'
}"
@load="loadPic" :src="src_path" :mode="model"></image>
</view>
</view>
</template>
<script>
/**
* 图片
* @property {Function} load 加载成功时触发返回图片宽高。
* @property {Function} click 点击图片事件,返回图片地址参数。
* @property {Function} error 图片加载出错时触发。
* @property {String} src = [] 默认:"",必填。图片地址。测试图片https://picsum.photos/300
* @property {Number} width = [] 默认0,宽度,非必填,单位rpx
* @property {Number} height = [] 默认0,高度,非必填,单位rpx
* @property {Number} round = [] 默认0,圆角,非必填
* @property {Boolean|String} previmage = [true|false] 默认true,点击图片是否预览。
* @property {String} model = [scaleToFill|aspectFit|aspectFill|widthFix|heightFix|top|bottom|center|left|right|top left|top right|bottom left|bottom right] 默认scaleToFill,图片展现模式,同官方。
* @example <tm-images src="https://picsum.photos/300"></tm-images>
*/
export default {
name: "tm-images",
props: {
src: {
type: String,
default: ""
},
//自动,宽度撑满容器宽度,高度自动。
// 自定宽度,
width: {
type: Number,
default: 0
},
// 自定高度。
height: {
type: Number,
default: 0
},
// 是否开启预览模式,即点击图片可以预览。
previmage: {
type: Boolean | String,
default: true
},
model: {
type: String,
default: 'scaleToFill'
},
round: {
type: Number|String,
default: 0
}
},
data() {
return {
w: 0,
h: 0,
isLoad:false,
isError:false
};
},
computed:{
w_px:function(){
return uni.upx2px(this.width);
},
h_px:function(){
return uni.upx2px(this.height);
},
src_path:function(){
if(
this.src.substring(0,4)=='http'||
this.src.substring(0,4)=='blob'||
this.src.substring(0,5)=='https'||
this.src.substring(0,3)=='ftp'||
this.src.indexOf('data:image')>-1
){
return this.src;
}
return '/'+this.src;
}
},
mounted() {
this.isLoad = true;
},
methods: {
error(e) {
this.isLoad = false;
this.isError = true;
this.$emit('error', e);
},
async loadPic(e) {
let wh = e.detail;
this.isLoad = false;
this.isError = false;
this.$nextTick(async function(){
this.$Querey(".tm-images",this,30).then(tb=>{
let sw = tb[0].width||wh.width;
let sh = tb[0].height||wh.height;
let bl = wh.width / wh.height;
if (this.w_px == 0 && this.h_px == 0) {
this.w = sw;
this.h = sw / bl;
this.$emit('load', {
width: this.w,
height: this.h
})
return;
}
if (this.w_px == 0 && this.h_px > 0) {
this.w = this.h_px * bl;
this.h = this.h_px
this.$emit('load', {
width: this.w,
height: this.h
})
return;
}
if (this.w_px > 0 && this.h_px == 0) {
this.w = this.w_px;
this.h = this.w_px / bl
this.$emit('load', {
width: this.w,
height: this.h
})
return;
}
if (this.w_px > 0 && this.h_px > 0) {
this.w = this.w_px;
this.h = this.h_px;
this.$emit('load', {
width: this.w,
height: this.h
})
return;
}
})
})
},
click(e) {
this.$emit("click", this.src_path);
if (this.previmage&&!this.isError) {
uni.previewImage({
current: this.src_path,
urls: [this.src_path],
fail:(res)=>{
}
})
}
}
},
}
</script>
<style lang="scss" scoped>
.tm-images{
line-height: 0;
.tm-images-load{
min-width: 60rpx;
min-height: 60rpx;
.load{
animation: xhRote 0.8s infinite linear;
}
}
}
@keyframes xhRote{
0%{
transform: rotate(0deg);
}
100%{
transform: rotate(360deg);
}
}
</style>