目录

分析过程

代码

如何使用


分析过程

首先我的思路以下

  1. 给图片预览上面加一个旋转按钮,
  2. 点击后顺时针旋转当前照片90度,
  3. 关闭预览,或切换照片,旋转恢复

vant的图片预览,也就是imagePreview组件,它提供了以下插槽

通过组件调用 ImagePreview 时,支持以下插槽:

名称说明参数
index自定义页码内容{ index: 当前图片的索引 }
cover自定义覆盖在图片预览上方的内容

        由于项目中之前使用得都是vant组件库中的Uploader组件,进行文件上传,这种方法调用图片预览得时候,是通过函数调用得,无法直接用图片预览组件,也就是说无法使用ImagePreview组件的插槽,(如果有能用的方法一定要告诉笔者)

        于是我只能够操控Uploader组件的插槽和监听方法,加上写过js创建动态dom的思路想到以下方法

  1. 点开预览的时候需要,动态生成button按钮的dom(这里是原生的按钮),把他挂载在渲染后的节点上,可以打开调试器,找到其中一个class名称,直接挂载,尽量让被挂载的dom是唯一的。
  2. 读取当前的页数,遍历所有的照片节点,得到页数对应的照片的dom,并且在点击后旋转
  3. 关闭,切换的时候删除按钮,因为这个按钮是通用的,并不是为所有的照片各自生成的按钮。

        于是剥离出来主要的要点

挂载的节点函数调用ImagePreview生成的页数节点的父节点(其他节点也可以)
事件预览图片打开,关闭,切换

通过阅读了Uploader组件的文档,刚好有点击和关闭的事件

click-preview点击预览图时触发同 after-read
close-preview关闭全屏图片预览时触发-

于是只缺一个图片切换的事件,通过阅读imagePreview组件拥有这个api

onChange切换图片时的回调函数,回调参数为当前索引Function-

于是父级就可以使用,监听切换事件的发生

:preview-options="{ onChange: resetTranf }"

代码

于是一切的准备好了

        由于代码过于繁杂,不可能每个页面都复制粘贴所有的代码,我想到了vue3的compositionAPI可以把整体代码抽离出来,之前还吐槽这个compositionAPI鸡肋,现在感觉是十分的友好,于是记得vue3的文档中说到vue2的mixin相当于是compositionAPI的前身,于是经过一顿倒腾,终于可以分离出来,在各个页面中引入,以下是代码

const uploaderMixin = {
  data() {
    return {
      rotate: 0, //旋转角度
    }
  },
  created() {},
  methods: {
    //旋转按钮
    tranformImg() {
      let imagePage = document.querySelector(".van-image-preview__index"); //获取图片页面显示的节点
      let imagePar = document.querySelector(".van-swipe__track"); //所有照片节点的父级
      const mytr = document.createElement("BUTTON"); //创建元素
      mytr.innerHTML =
        "<svg t='1644461181099' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='2245' width='30' height='30'><path d='M961.45 362.18V137.45l-96.93 96.93C781.45 128.89 652.62 61.16 507.58 62.57 271.24 64.85 72.15 257.78 62.9 493.94 52.86 750.39 257.78 961.45 512 961.45c166.26 0 311.09-90.52 388.83-224.73h-43.78C775.39 861.87 627.8 940.06 463.37 921.2c-187.7-21.52-339.93-174.33-360.76-362.11C75.05 310.47 268.94 100 512 100c132.91 0 250.39 63.49 325.7 161.21L736.73 362.18h224.72z' fill='#eaf0ec' p-id='2246'></path></svg>"; //元素内容,这一堆是阿里巴巴矢量图
      imagePage.appendChild(mytr); //添加到这个节点之后
      mytr.classList.add("ratClass"); //添加类名方便删除
      mytr.addEventListener("click", () => {
        //获取当前页数,因为有空格所以-1
        let index = imagePage.innerHTML.slice(
          0,
          imagePage.innerHTML.indexOf("/") - 1
        ); //获取当前照片下标
        //找到这个照片让他旋转,因为页数和数组下标不一致所以-1,这里之所以子节点的子节点,使用者可以打印出来看一下为什么这样,我是通过一层一层查看才发现这个是图片的节点
        imagePar.childNodes[
          index - 1
        ].childNodes[0].style.transform = `rotate(${(this.rotate += 90)}deg)`;
      });
      //按钮样式
      mytr.style.color = "white";
      mytr.style.backgroundColor = "#181e1e91";
      mytr.style.border = "0px";
      mytr.style.position = "absolute";
      mytr.style.top = "25px";
      mytr.style.width = "32px";
      mytr.style.left = "-3px";
      mytr.style.cursor = 'pointer'
    },
    resetTranf() {
      this.rotate = 0;
      let imagePar = document.querySelector(".van-swipe__track"); //父级
      //让所有得照片得旋转角度清空
      if (imagePar.childNodes.length) {
        for (let i = 0; i < imagePar.childNodes.length; i++) {
          if (imagePar.childNodes[i].childNodes[0]) {
            imagePar.childNodes[i].childNodes[0].style.transform =
              "rotate(0deg)";
          }
        }
      }
    },
    deleteBtn() {
      this.rotate = 0;
      //移除旋转
      document.querySelector(".ratClass").remove();
    },
  }
}
export default uploaderMixin

如何使用

关于如何使用,把这些代码复制粘贴到空文件,改名称为 uploaderMixin.js

第一步,在使用的vue文件上传组件中,加上一个属性,两个方法,

closeable是是否显示文件预览的关闭按钮

onchange是预览图片切换的时候触发

		<van-uploader
			:preview-options="{ closeable: true, onChange: resetTranf }"
            @click-preview="tranformImg"
            @close-preview="deleteBtn"
		/>

第二步,引入和导出


import uploaderMixin from "@/components/mixin/uploaderMixin";
export default { //一定要在导出这注册,否则不出效果
	  mixins: [uploaderMixin],
}

若有更好的方法,希望能够告诉笔者,若代码有可以优化的地方望告知。

若有不理解希望互相解答。 

Logo

前往低代码交流专区

更多推荐