vue2使用vant组件库用Uploader组件时,给预览图片添加旋转按钮,并且使其进行旋转
首先我的思路以下给图片预览上面加一个旋转按钮,点击后顺时针旋转当前照片90度,关闭预览,或切换照片,旋转恢复vant的图片预览,也就是imagePreview组件,它提供了以下插槽通过组件调用 ImagePreview 时,支持以下插槽:名称说明参数index自定义页码内容{ index: 当前图片的索引 }cover自定义覆盖在图片预览上方的内容由于项目中之前使用得都是vant组件库中的Uplo
目录
分析过程
首先我的思路以下
- 给图片预览上面加一个旋转按钮,
- 点击后顺时针旋转当前照片90度,
- 关闭预览,或切换照片,旋转恢复
vant的图片预览,也就是imagePreview组件,它提供了以下插槽
通过组件调用 ImagePreview
时,支持以下插槽:
名称 | 说明 | 参数 |
---|---|---|
index | 自定义页码内容 | { index: 当前图片的索引 } |
cover | 自定义覆盖在图片预览上方的内容 |
由于项目中之前使用得都是vant组件库中的Uploader组件,进行文件上传,这种方法调用图片预览得时候,是通过函数调用得,无法直接用图片预览组件,也就是说无法使用ImagePreview组件的插槽,(如果有能用的方法一定要告诉笔者)
于是我只能够操控Uploader组件的插槽和监听方法,加上写过js创建动态dom的思路想到以下方法
- 点开预览的时候需要,动态生成button按钮的dom(这里是原生的按钮),把他挂载在渲染后的节点上,可以打开调试器,找到其中一个class名称,直接挂载,尽量让被挂载的dom是唯一的。
- 读取当前的页数,遍历所有的照片节点,得到页数对应的照片的dom,并且在点击后旋转
- 关闭,切换的时候删除按钮,因为这个按钮是通用的,并不是为所有的照片各自生成的按钮。
于是剥离出来主要的要点
挂载的节点 | 函数调用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],
}
若有更好的方法,希望能够告诉笔者,若代码有可以优化的地方望告知。
若有不理解希望互相解答。
更多推荐
所有评论(0)