需求

本文想要实现的样式是,通过任意事件,比如点击图片或点击按钮,触发一个全屏的图片预览。

看一看element官网中的例子:

点击这个图片
image.png
就会出现全屏的大图预览
image.png

这个大图可以自由缩放,多张图片可以切换,而且大图的url和小图的url并没有关系。

但element这个<el-image>组件存在一个问题:它的大图必须通过点击小图触发,而文档上并没有点击事件的接口。

这就意味着,无法实现“点击其他自定义的按钮来显示大图”,只能“点击<el-image/>小图”来调用它内部的事件。

其他的解决方法——<el-image-viewer/>

其他文章中给出了一个办法:

element中的大图本质是另一个组件<el-image-viewer/>,“点击小图显示大图”的过程就是<el-image>点击之后显示了<el-image-viewer/>
虽然<el-image-viewer/>没有在文档中被给出,但可以直接使用,只需要额外的控制它的显隐即可。

具体用法可以看链接。

本文的方法——用代码触发“点击”事件

本文的方法比较简单粗暴,共两步:

  1. 把小图的宽高设为0
  2. 在需要时用代码模拟一下小图的点击事件

这样规范吗?显然是不规范,但上班的代码又不是开源项目,能跑即可,要什么自行车。

先来看文档中给出的示例代码:

<template>
  <div class="demo-image__preview">
    <el-image
      style="width: 100px; height: 100px"
      :src="url"
      :zoom-rate="1.2"
      :preview-src-list="srcList"
      :initial-index="4"
      fit="cover"
    />
  </div>
</template>

<script lang="ts" setup>
const url =
  'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg'
const srcList = [
  'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
  'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
  'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
  'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
  'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
  'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
  'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg',
]
</script>

<style scoped>
.demo-image__error .image-slot {
  font-size: 30px;
}
.demo-image__error .image-slot .el-icon {
  font-size: 30px;
}
.demo-image__error .el-image {
  width: 100%;
  height: 200px;
}
</style>

在依赖环境正确的情况下,复制到合适位置就可以正常使用。

接下来对它进行修改。

1.获取引用

要想模拟点击,前提就是获取dom元素的引用。
VUE中有三种获取的方式,本文以最简单的document方式举例。
给元素加个id:

    <el-image
      id="show-image"
      style="width: 100px; height: 100px"
      :src="url"
      其他参数略
    />

此时,如果在ts中执行document.getElementById('show-image').click()就可以显示大图了。

这一步测试成功之后就可以把document.getElementById('show-image').click()绑定到其他事件上,比如某个按钮的点击,这样就实现了“点击按钮显示大图”

2.设置宽高为0

因为<el-image-viewer/><el-image/>完全就是两个组件,所以小图不会影响大图,直接置0即可:

    <el-image
      id="show-image"
      style="width: 100px; height: 100px"
      :src="url"
      其他参数略
    />

此时页面上就不会再显示它了,而触发事件仍然能正常显示大图。

3.改变大图

目前的大图url是写死的,如果想让图片变化就得把url数组传进来。
这里补充一个基本知识:

在vue中,如果只用let定义变量,而且页面使用了这个变量,当组件渲染完成后,再去改变let变量的值,组件中不会跟着变化。如果想让组件能变化,必须使用ref定义引用变量。

也就是:

let srcList = ref([
  'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
  'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
  'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
  'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
  'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
  'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
  'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg',
])

如果后续想让url变化,需要用srcList.value = 来改变变量的值。

类似这样(用mitt实现,也可以用其他方式实现,只要能调用到这两行代码即可):

    // 当其他组件弹射时,先修改url的值,再模拟点击一下图片
    bus.on("showImg", ({ data: data }) => {
      srcList.value = data;
      document.getElementById('show-image').click()
    })

这样就实现了通过其他的事件触发<el-image-viewer/>大图的效果。

总结

非常简单粗暴,上班的代码能跑即可,节约时间。


LYX6666
1.6k 声望73 粉丝

一个正在茁壮成长的零基础小白