uni-app --image组件封装

256 阅读1分钟

组件<lj-img>是对uni-app原有组件<image>进行二次封装。

功能:默认兜底图,缓存,无缝切换。

开放配置信息

属性类型默认值备注
srcString--资源文件路径
defSrcString/static/default-img.jpg兜底图片路径
modeStringaspectFill图片裁剪、缩放的模式 uniapp 组件自带属性
widthString100%图片宽度
heightString100%图片高度
borderRadiusString图片圆角圆角属性通过style继承的会有兼容性问题
file_keyString--图片缓存标志

兜底图实现

     <image
      v-if="!loaded"
      class="img"
      :src="defSrc"
      :mode="mode"
      :style="`width: ${width};height:${height};border-radius: ${borderRadius};`"
    />
  • 默认图路径为defSrc
  • 默认图在资源图loadded事件完成之前展示

缓存实现

async created() {
    if (!this.file_key) {
      this.cacheImgUrl = this.src;
      return;
    }
    const url = uni.getStorageSync(this.file_key);
    if (!url) {
      this.cacheImgUrl = this.src;
      const path = await this.downloadImg(this.src);
      const longPath = await this.saveFile(path);
      uni.setStorageSync(this.file_key, longPath);
    } else {
      this.cacheImgUrl = url;
    }
  },
watch: {
    src: {
      async handler(value) {
        if (!this.file_key) {
          this.cacheImgUrl = value;
          this.loaded = false;
          return;
        }
        const url = uni.getStorageSync(this.file_key);
        if (!url) {
          this.cacheImgUrl = value;
          const path = await this.downloadImg(value);
          const longPath = await this.saveFile(path);
          uni.setStorageSync(this.file_key, longPath);
        } else {
          this.cacheImgUrl = url;
        }
      },
    },
  },

缓存实现

  • 判断是否传入缓存标志,没传则用原图
  • 判断是否已有缓存,有则取已有的缓存路径
  • 缓存
    1. uni.downloadFile先下载资源到临时路径
    2. uni.saveFile 将临时文件保存为本地图片 不同端存储路径各不相同
    3. 将本地图片路径存储到localstorage
  • 图片更换也要将新图片进行缓存
  • 缓存被清理或其他错误通过@error="handlerErr"监听错误重新下载缓存文件

无缝切换

在image元素的src改变之后会重新加载,造成闪屏。无缝切换就是避免闪屏出现进行优化。

    handlerLoad() {
      if (this.defSrc === "/static/default-img.jpg") {
        this.loaded = true;
      } else {
        setTimeout(() => {
          this.loaded = true;
        }, 200);
      }
    },
  • 通过动态传递defsrc,将原图路径作为默认图路径传入兜底图中
  • 在新图片触发loaded的时候,再延迟加载新图片即可避免闪屏