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

220 lines
6.8 KiB

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