2022-06-08 15:48:09 +08:00

157 lines
4.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<image
class="img-cache"
:src="resource"
: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)"
>
</image>
</template>
<script>
// #ifdef APP-PLUS
import download from './download'
import { resolveFile, storage } from './index'
// #endif
/**
* ImgCache 图片缓存
* @description APP端图片缓存
* @tutorial https://ext.dcloud.net.cn/plugin?id=2515
* @property {string} src 图片资源地址
* @property {string} mode 图片裁剪、缩放的模式
* @property {boolean} lazyLoad 是否图片懒加载
* @property {boolean} fade-show 图片显示动画效果
* @property {boolean} webp 默认不解析 webP 格式,只支持网络资源
* @property {boolean} show-menu-by-longpress 开启长按图片显示识别小程序码菜单
* @property {string} dir 缓存的文件目录文件夹开头不能有_
* @property {string} width 宽度,单位任意,如果为数值,则为 rpx 单位
* @property {string} height 高度,单位任意,如果为数值,则为 rpx 单位
* @property {object} custom-style 自定义样式
* @event {Function} click 点击图片
* @event {Function} error 错误发生
* @event {Function} load 图片载入完毕
* @example <img-cache src="https://example.com/image.png"></img-cache>
*/
export default {
name: 'ImgCache',
props: {
src: {
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
},
dir: {
type: String,
default: 'imgcache'
},
width: {
type: [String, Number]
},
height: {
type: [String, Number]
},
customStyle: {
type: Object,
default: () => ({})
}
},
data() {
return {
resource: ''
}
},
computed: {
style() {
const style = { willChange: 'transform' }
// 判断传过来的值是否为 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: {
src: {
handler: 'init',
immediate: true
}
},
methods: {
// 初始化
init() {
// #ifdef APP-PLUS
this.fnCache()
// #endif
// #ifndef APP-PLUS
this.setSrc()
// #endif
},
// 获取缓存
async fnCache() {
const url = this.src // 赋值到新变量,避免下载时 src 更改,从而网络地址和本地地址图片不一致
if (!/^https?:\/\//.test(url)) return this.setSrc() // 判断是否网络地址
const [select] = storage.select({ url }) // 查询缓存是否存在
if (select) {
const path = select.local
if (await resolveFile(path)) return this.setSrc(path) // 判断本地文件是否存在 如果存在则显示本地文件
storage.delete(select) // 如果本地文件不存在则删除缓存数据
}
this.setSrc()
const local = await download(url, this.dir) // 下载文件
if (local) storage.insert({ url, local }) // 缓存数据
},
// 设置图片资源地址
setSrc(src) {
this.resource = src || this.src
console.log(src)
},
// 添加单位如果为数值则为rpx单位否则直接返回
addUnit(value) {
value = String(value)
return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value) ? `${value}rpx` : value
},
// 发送事件
fnEvent(emit, event) {
this.$emit(emit, event)
}
}
}
</script>