首页 前端知识 vue uniapp 自定义图片预览,实现 uni.previewImage() API 功能

vue uniapp 自定义图片预览,实现 uni.previewImage() API 功能

2024-03-04 10:03:31 前端知识 前端哥 559 864 我要收藏

最近写手机端项目的时候,用的是uniapp + uView,然后出现好多bug。

  1. uni.showToast() 失效,只能用 u-toast 组件来替代。
  2. uni.previewImage() 失效,于是就导致 u-upload 图片上传组件默认的图片预览功能也失效。

然后急着要用图片预览这个功能,索性自己手写一个最基础的图片预览。

1. 效果图

在这里插入图片描述![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b36c91f668af4000a8668c2c0304301c.png

2. 引用

简单封装的一个组件,直接在 components 文件夹下创建一个相同名字的目录和vue文件,免注册直接引入。

<template>
	<g-previewImage :show="preview.show" :url="preview.url" @close="preview.show = false"></g-previewImage>
</template>
<script>
	export default {
		data() {
			return {
				preview: {
					show: false,
					url: ""
				}
			}
		}
	}
</script>

g-previewImage.vue

<template>
	<view class="g-previewImage" v-if="show">
		<view class="image" :style="{width, height}">
			<image :src="url" :mode="mode"></image>
		</view>
		<u-icon class="icon" name="close" color="#eee" @click="close"></u-icon>
	</view>
</template>

<script>
	export default {
		name: "PreviewImage",
		props: {
			show: {
				type: Boolean,
				default: false
			},
			url: {
				type: String,
				default: ''
			}
		},
		data() {
			return {
				isshow: false,
				width: 0,
				height: 0,
				mode: 'aspectFit' // 保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
			}
		},
		watch: {
			show: {
				handler(n) {
					this.isshow = n
				},
				immediate: true
			},
			url: {
				handler(n) {
					if (n) {
						const img = new Image()
						img.src = n
						this.width = img.width > img.height ? '100%' : img.width + 'px'
						this.height = img.height > img.width ? '100%' : img.height + 'px'
					}
				},
				immediate: true
			}
		},
		methods: {
			open() {
				this.$emit('change', true)
			},
			close() {
				this.$emit('close')
			}
		}
	}
</script>

<style lang="scss" scoped>
	.g-previewImage {
		display: flex;
		align-items: center;
		justify-content: center;
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-color: rgba(0, 0, 0, .5);
		z-index: 99999;

		.image {

			// background-color: pink;
			image {
				width: 100%;
				height: 100%;
			}
		}

		.icon {
			position: absolute;
			top: 40rpx;
			right: 40rpx;
		}
	}
</style>
3. 改进

组件注册引入的方式是救急方案,略显繁琐了,那可不可以做成 uni.previewImage() API 那种 js 直接调用的形式呢?
当然可以实现了!我们就来实现个翻版的 uni.previewImage() API ,主要是通过 Vue.extend() 实现。

preview.js

import Vue from 'vue'
import preview from "@/components/previewImage"
// 创建一个 预览组件类
const previewImg = Vue.extend(preview)

class Preview {
	constructor() {
		// 组件实例挂载
		this.instance = new previewImg().$mount()
		document.body.appendChild(this.instance.$el)
	}
	// 定义一个 open 函数,调用实例中的 open 函数
	open(url) {
		this.instance.open(url)
	}
}

export default new Preview()

main.js

import Preview from "@/static/js/preview.js"
Vue.prototype.$preview = Preview

previewImage.vue

<template>
	<view class="g-previewImage" v-if="show">
		<view class="image" :style="{width, height}">
			<image :src="link" :mode="mode"></image>
		</view>
		<u-icon class="icon" name="close" color="#eee" @click="close"></u-icon>
	</view>
</template>

<script>
	export default {
		name: "PreviewImage",
		data() {
			return {
				link: "",
				show: false,
				width: 0,
				height: 0,
				mode: 'aspectFit' // 保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
			}
		},
		methods: {
			open(url) {
				const img = new Image()
				img.src = url
				this.width = img.width > img.height ? '100%' : img.width + 'px'
				this.height = img.height > img.width ? '100%' : img.height + 'px'
				this.link = url
				this.show = true
			},
			close() {
				this.show = false
			}
		}
	}
</script>

<style lang="scss" scoped>
	.g-previewImage {
		display: flex;
		align-items: center;
		justify-content: center;
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-color: rgba(0, 0, 0, .5);
		z-index: 99999;

		.image {

			// background-color: pink;
			image {
				width: 100%;
				height: 100%;
			}
		}

		.icon {
			position: absolute;
			top: 40rpx;
			right: 40rpx;
		}
	}
</style>

应用:this.$preview.open(url)

</template>
	<view class="content">
		<image :src="url" mode="aspectFit" @click="preview(url)"></image>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				url: require('../../static/img/1.jpg'),
			}
		},
		methods: {
			preview(url) {
				this.$preview.open(url)
			}
		}
	}
</script>
转载请注明出处或者链接地址:https://www.qianduange.cn//article/3212.html
标签
uni-app
评论
发布的文章

Jquery提供的load方法

2024-03-26 08:03:18

echarts:去掉markLine

2024-03-26 08:03:08

jQuery总结

2024-03-11 10:03:12

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!