|
|
<template>
|
|
|
<image
|
|
|
v-if="img_url"
|
|
|
:src="img_url"
|
|
|
:mode="mode"
|
|
|
:lazy-load="lazyLoad"
|
|
|
:fade-show="fadeShow"
|
|
|
:webp="webp"
|
|
|
:show-menu-by-longpress="showMenuByLongpress"
|
|
|
:style="[style]"
|
|
|
@tap="fnEvent('click', $event)"
|
|
|
@error="fnEvent('error', $event)"
|
|
|
@load="fnEvent('load', $event)"
|
|
|
/>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import { storage,config,CHCHEPREFIX } from '@/util/index'
|
|
|
// 获取全局唯一的文件管理器
|
|
|
const fileSystemManager = uni.getFileSystemManager()
|
|
|
/**
|
|
|
* kingImageCache 图片缓存
|
|
|
* @description 图片缓存
|
|
|
* @property {string} imgSrc 图片资源地址
|
|
|
* @property {string} mode 图片裁剪、缩放的模式
|
|
|
* @property {boolean} lazyLoad 图片懒加载。只针对page与scroll-view下的image有效
|
|
|
* @property {boolean} fade-show 图片显示动画效果
|
|
|
* @property {boolean} webp 默认不解析 webP 格式,只支持网络资源
|
|
|
* @property {boolean} show-menu-by-longpress 开启长按图片显示识别小程序码菜单
|
|
|
* @property {string} prefixTxt 缓存的文件
|
|
|
* @property {string} width 宽度,单位任意,如果为数值,则为 rpx 单位
|
|
|
* @property {string} height 高度,单位任意,如果为数值,则为 rpx 单位
|
|
|
* @property {object} custom-style 自定义样式
|
|
|
* @property {object} defaultImg 默认图片
|
|
|
* @event {Function} click 点击图片
|
|
|
* @event {Function} error 错误发生
|
|
|
* @event {Function} load 图片载入完毕
|
|
|
*/
|
|
|
export default {
|
|
|
props: {
|
|
|
imgSrc: {
|
|
|
type: String,
|
|
|
},
|
|
|
mode: {
|
|
|
type: String,
|
|
|
default: 'scaleToFill',
|
|
|
},
|
|
|
lazyLoad: {
|
|
|
type: Boolean,
|
|
|
default: false,
|
|
|
},
|
|
|
fadeShow: {
|
|
|
type: Boolean,
|
|
|
default: true,
|
|
|
},
|
|
|
webp: {
|
|
|
type: Boolean,
|
|
|
default: false,
|
|
|
},
|
|
|
showMenuByLongpress: {
|
|
|
type: Boolean,
|
|
|
default: false,
|
|
|
},
|
|
|
prefixTxt: {
|
|
|
type: String,
|
|
|
default: '',
|
|
|
},
|
|
|
width: {
|
|
|
type: [String, Number],
|
|
|
},
|
|
|
height: {
|
|
|
type: [String, Number],
|
|
|
},
|
|
|
customStyle: {
|
|
|
type: Object,
|
|
|
default: () => ({}),
|
|
|
},
|
|
|
defaultImg: {
|
|
|
type: String,
|
|
|
default: '',
|
|
|
},
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
img_url: '',
|
|
|
prefix:'',
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
style() {
|
|
|
const style = {}
|
|
|
// 判断传过来的值是否为 undefined null false ''
|
|
|
const isEmpty = (val) => [undefined, null, false, ''].includes(val)
|
|
|
!isEmpty(this.width) && (style.width = this.addUnit(this.width))
|
|
|
!isEmpty(this.height) && (style.height = this.addUnit(this.height))
|
|
|
return {
|
|
|
...style,
|
|
|
...this.customStyle,
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
watch: {
|
|
|
img_url: {
|
|
|
handler: async function (new_url, old_url) {
|
|
|
console.log("url>>>>>", new_url, old_url);
|
|
|
// 如果没有标识,默认一个
|
|
|
if (!this.prefixTxt) {
|
|
|
this.prefix = CHCHEPREFIX.default_temp
|
|
|
}
|
|
|
const prefixList = storage(this.prefix)
|
|
|
// 获取缓存文件,没有直接下载
|
|
|
if (prefixList) {
|
|
|
const storageList = JSON.parse(prefixList) ? JSON.parse(prefixList) : prefixList
|
|
|
// 存在图片缓存
|
|
|
if (storageList[this.imgSrc]) {
|
|
|
const imgSrcList = storageList[this.imgSrc]
|
|
|
const hasSavedFile = await this.checkSaveFile(imgSrcList)
|
|
|
// 如果本地文件还存在,防止用户自动清除本地缓存,而storage不存在的问题
|
|
|
if (hasSavedFile) {
|
|
|
this.img_url = imgSrcList
|
|
|
} else {
|
|
|
// 删除storage里面这一项
|
|
|
delete storageList[this.imgSrc]
|
|
|
// 如果是临时储存,有过期时间
|
|
|
if (this.prefix.includes('temp')) {
|
|
|
storage(this.prefix, JSON.stringify(storageList), config.imageCacheTime)
|
|
|
} else {
|
|
|
storage(this.prefix, JSON.stringify(storageList))
|
|
|
}
|
|
|
this.downImageFile()
|
|
|
}
|
|
|
} else {
|
|
|
this.downImageFile()
|
|
|
}
|
|
|
} else {
|
|
|
this.downImageFile()
|
|
|
}
|
|
|
},
|
|
|
immediate: true,
|
|
|
},
|
|
|
},
|
|
|
methods: {
|
|
|
// 判断文件/目录是否存在
|
|
|
checkSaveFile(path) {
|
|
|
return new Promise((resolve) => {
|
|
|
fileSystemManager.access({
|
|
|
path,
|
|
|
success: (res) => {
|
|
|
// 如果本地储存文件
|
|
|
if (res.errMsg === 'access:ok') {
|
|
|
resolve(true)
|
|
|
} else {
|
|
|
resolve(false)
|
|
|
}
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
resolve(false)
|
|
|
},
|
|
|
})
|
|
|
})
|
|
|
},
|
|
|
// 添加单位,如果为数值则为rpx单位,否则直接返回
|
|
|
addUnit(value) {
|
|
|
value = String(value)
|
|
|
return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value) ? `${value}rpx` : value
|
|
|
},
|
|
|
// 下载缓存文件
|
|
|
downImageFile() {
|
|
|
// 如果已经是缓存,不用做处理了
|
|
|
if (this.img_url.includes('://tmp')) {
|
|
|
return
|
|
|
}
|
|
|
// 下载文件
|
|
|
uni.downloadFile({
|
|
|
url: this.imgSrc,
|
|
|
success: (ress) => {
|
|
|
if (ress.statusCode === 200) {
|
|
|
const prefixList = storage(this.prefix)
|
|
|
// 如果存在缓存
|
|
|
if (prefixList) {
|
|
|
const storageList = JSON.parse(prefixList) ? JSON.parse(prefixList) : prefixList
|
|
|
// 如果不存在图片缓存
|
|
|
if (!storageList[this.imgSrc]) {
|
|
|
// 设置图片缓存
|
|
|
storageList[this.imgSrc] = ress.tempFilePath
|
|
|
// 如果是临时储存,有过期时间
|
|
|
if (this.prefix.includes('temp')) {
|
|
|
storage(this.prefix, JSON.stringify(storageList), config.imageCacheTime)
|
|
|
} else {
|
|
|
storage(this.prefix, JSON.stringify(storageList))
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
const params = {}
|
|
|
params[this.imgSrc] = ress.tempFilePath
|
|
|
// 如果是临时储存,有过期时间
|
|
|
if (this.prefix.includes('temp')) {
|
|
|
storage(this.prefix, JSON.stringify(params), config.imageCacheTime)
|
|
|
} else {
|
|
|
storage(this.prefix, JSON.stringify(params))
|
|
|
}
|
|
|
}
|
|
|
this.img_url = ress.tempFilePath
|
|
|
} else {
|
|
|
this.img_url = ''
|
|
|
}
|
|
|
},
|
|
|
fail: () => {
|
|
|
this.img_url = ''
|
|
|
},
|
|
|
})
|
|
|
},
|
|
|
// 发送事件
|
|
|
fnEvent(emit, event) {
|
|
|
this.$emit(emit, event)
|
|
|
},
|
|
|
},
|
|
|
}
|
|
|
</script>
|