202 lines
4.6 KiB
Vue
202 lines
4.6 KiB
Vue
<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>
|