当前位置: 首页 > web >正文

uniapp H5预览图片组件

前言

uniapp的预览API, uni.previewImage预览长图在H5环境下长图会模糊

如下图:
在这里插入图片描述
手指可以撑开放大, 但会模糊
解决方法:
使用自定义全局预览接口
global-preview-image/index.vue

<template><view v-if="show" class="preview-mask" @click.stop="hide"><!-- 图片预览遮罩层 --><swiperclass="preview-swiper":current="current"duration="300"@change="swiperChange"><!-- 遍历图片地址列表,生成轮播项 --><swiper-item v-for="(item, index) in urls" :key="index"><movable-area class="movable-area"><movable-view class="movable-view" scale scale-min="1"><scroll-view scroll-y class="preview-item"><viewclass="preview-image-box":style="{alignItems:imagesHeight[index] >= windowHeight? 'flex-start': 'center',}"><imageclass="preview-image":class="[`preview-image-${index}`]":src="item":lazy-load="true"mode="widthFix"@click.stop="hide"@load="load(index)"/></view></scroll-view></movable-view></movable-area></swiper-item></swiper><!-- 显示当前图片索引和总数 --><text class="preview-index">{{ current + 1 }}/{{ urls.length }}</text></view>
</template><script>
export default {data() {return {show: false, // 控制预览组件是否显示urls: [], // 图片地址列表loadSuccess: [], // 已加载成功的图片索引列表current: 0, // 当前显示的图片索引windowHeight: 0, // 设备高度imagesHeight: [], // 图片高度列表}},mounted() {/*** 组件挂载时获取系统窗口高度信息*/uni.getSystemInfo({success: (res) => {this.windowHeight = res.windowHeight},})},methods: {/*** 打开图片预览组件* @param {Object} options - 配置参数* @param {Array} options.urls - 图片地址数组* @param {Number} options.current - 当前显示的图片索引*/open({ urls = [], current = 0 }) {uni.showLoading({title: "加载中...",})// 如果urls不为空且current为字符串,则查找current在urls中的索引位置if (urls.length > 0 && typeof current === "string") {current = urls.findIndex((item) => item === current)current = current >= 0 ? current : 0}// 设置组件数据this.urls = urls || []this.loadSuccess = []this.imagesHeight = Array(urls.length).fill(0)this.current = current || 0this.show = true},/*** 关闭图片预览组件*/hide() {this.show = falseuni.hideLoading()setTimeout(() => {this.urls = []}, 300)},/*** 图片加载完成回调* @param {Number} i - 图片索引*/load(i) {if (!this.loadSuccess.includes(i)) this.loadSuccess.push(i)// 如果当前图片已加载完成且为当前显示图片,则隐藏加载提示if (this.loadSuccess.includes(i) && this.current == i) {uni.hideLoading()}// 获取元素const query = uni.createSelectorQuery().in(this)// 获取元素高度query.select(".preview-image-" + i).boundingClientRect((res) => {this.$set(this.imagesHeight, i, res.height)}).exec()},/*** 轮播图切换事件处理* @param {Object} e - 事件对象,包含 detail.current 表示当前切换到的图片索引*/swiperChange(e) {// 根据切换后的图片索引判断是否显示加载提示if (this.loadSuccess.includes(e.detail.current)) {uni.hideLoading()} else {uni.showLoading({title: "加载中...",})}this.current = e.detail.current},},
}
</script><style scoped>
/* 预览遮罩层样式 */
.preview-mask {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background-color: rgba(0, 0, 0, 0.9);z-index: 9999;display: flex;justify-content: center;align-items: center;
}/* 轮播图容器样式 */
.preview-swiper {width: 100%;height: 100%;
}/* 预览项容器样式 */
.preview-item {width: 100vw;height: 100vh;
}
.preview-image-box {display: flex;
}
/* 图片及可移动视图相关样式 */
.preview-image,
.preview-image-box,
.movable-view,
.movable-area {width: 100%;height: 100%;
}/* 可移动视图样式 */
.movable-view {
}/* 预览图片样式 */
.preview-image {display: block;
}/* 图片索引文本样式 */
.preview-index {position: absolute;bottom: 60rpx;color: #fff;font-size: 32rpx;
}
</style>

挂载body上
global-preview-image/index.js

import Vue from 'vue'
import PreviewImage from './index.vue'const PreviewImageConstructor = Vue.extend(PreviewImage)
let instance/*** 初始化预览图片实例* 创建PreviewImage组件实例并将其挂载到DOM中*/
function initInstance() {instance = new PreviewImageConstructor({el: document.createElement('div')})document.body.appendChild(instance.$el)
}/*** 预览图片函数* @param {Object|String} options - 预览配置选项,如果是字符串则作为单张图片URL处理* @param {Array} options.urls - 图片URL数组* @param {Number} options.current - 当前显示图片的索引* @param {Boolean} options.loop - 是否可以循环预览* @param {Function} options.success - 接口调用成功的回调函数* @param {Function} options.fail - 接口调用失败的回调函数* @param {Function} options.complete - 接口调用结束的回调函数*/
function previewImage(options) {// 如果实例不存在,则初始化实例if (!instance) {initInstance()}// 如果传入的是字符串,则转换为包含单个URL的对象格式if (typeof options === 'string') {options = {urls: [options]}}// 调用实例的open方法打开图片预览instance.open(options)
}/*** 插件安装函数* @param {Object} Vue - Vue构造函数*/
function install(Vue) {// 将previewImage方法挂载到Vue原型上,使所有Vue实例都可以访问Vue.prototype.$previewImage = previewImage// 挂载到uni对象if (typeof uni !== 'undefined') {uni.previewImage = previewImage}
}export default {install,previewImage
}

main.js引入

...
// #ifdef H5
import PreviewImage from '@/components/global-preview-image'
// #endif
...
// #ifdef H5
Vue.use(PreviewImage)
// #endif
...
http://www.xdnf.cn/news/19811.html

相关文章:

  • 在VS Code中直接操控浏览器
  • CodeForge v25.0.3 发布:Web 技术栈全覆盖,编辑器个性化定制新时代
  • USB4与PCIe的技术融合:新一代接口协议的架构革新
  • 【论文阅读】Neuro-Symbolic Integration Brings Causal and Reliable Reasoning Proofs
  • 【报错记录】OpenGauss/磐维数据库连接报:org.postgresql.util.PSQLException: 致命错误: 账户被锁定
  • 分公司、工厂、出差人员远程访问办公系统,如何安全稳定又省钱?
  • HTML第六课:表格展示
  • 腾讯开源WMT2025冠军大模型:拿下30个第一,同类最佳
  • 2025 年普通人还可以期待 NFT 交易市场吗?
  • Meta生成式推荐:重塑万亿级推荐系统
  • FastAPI 介绍及示例开发
  • 深度学习之第五课卷积神经网络 (CNN)如何训练自己的数据集(食物分类)
  • 安装wsl报错0x800701bc
  • mapbox高阶,结合threejs(threebox)添加管道,实现管道流动效果
  • 数据库的锁级别
  • HTML5 简介和基础骨架
  • 快速生成商品图:4款国内免费AI工具盘点
  • 【golang长途旅行第36站】golang操作Redis
  • Vue基础知识-localStorage 与 sessionStorage
  • 华为HCIE认证:三年有效期值不值得?
  • 苹果开发中什么是Storyboard?object-c 和swiftui 以及Storyboard到底有什么关系以及逻辑?优雅草卓伊凡
  • 一款开源的CMS系统简介
  • 告别侵权风险!4家优质商用音乐平台盘点,本土创作者首选推荐!
  • 使用Java获取本地PDF文件并解析数据
  • 深度优先 一直往一个方向走,可用递归或者栈实现
  • 点燃汽车电子与高端制造的“合规·高效·智能”引擎—— 全星研发项目管理软件系统APQP软件系统
  • vim中常见操作及命令
  • 浏览器内存 (JavaScript运行时内存)存储的优劣分析
  • 常见机械机构的图graph表示
  • LeetCode 844.比较含退格的字符串