import { h, render } from 'vue'; import { ElImageViewer } from 'element-plus'; import { downloadImgVideo } from '@/utils' export default function (app) { app.directive('previewImage', { mounted(el, binding) { const previewBox = document.createElement('div'); previewBox.classList.add('preview-box'); let vnode; let downloadIndex // 判断是否为视频文件 const isVideo = (url) => /\.(mp4|webm|ogg)$/i.test(url); // 创建混合媒体预览组件 const createMixedMediaViewer = (urls, initialIndex = 0) => { const mediaList = urls.map(url => ({ url, isVideo: isVideo(url) })); const _el = h(ElImageViewer, { urlList: urls, initialIndex, hideOnClickModal: true, onClose: () => { render(null, previewBox); document.body.removeChild(previewBox); }, onSwitch: (index) => { downloadIndex = index const elAll = document.querySelectorAll('.el-image-viewer__img'); const el = elAll[index]; if (!isVideo(el.src) || el.tagName !== 'VIDEO') { // 当前是 IMG elAll.forEach((item, i) => { if (item.tagName === 'VIDEO') { item.style.display = 'none' } }) } else { el.style.display = 'block' } if (isVideo(el.src) && el.tagName === 'IMG') { const currentMedia = mediaList[index]; const canvasElement = document.querySelector('.el-image-viewer__canvas'); // 如果是视频,替换img标签为video标签 setTimeout(() => { if (canvasElement) { const videoElement = document.createElement('video'); videoElement.src = currentMedia.url; videoElement.controls = true; videoElement.autoplay = true; videoElement.className = el.className; videoElement.style.maxWidth = '100%'; videoElement.style.maxHeight = '100%'; canvasElement.appendChild(videoElement); el.remove() } }, 0); } } }); return _el }; el.addEventListener('click', () => { el.style.cursor = 'pointer'; const urls = Array.isArray(binding.value[0]) ? binding.value[0] : [binding.value[0]]; const initialIndex = binding.value[1] || 0; downloadIndex = initialIndex vnode = createMixedMediaViewer(urls, initialIndex); render(vnode, previewBox); document.body.appendChild(previewBox); // 添加下载按钮 const action_btn = previewBox.children[0].children[4].children[0] const divider = document.createElement('i') divider.className = 'el-image-viewer__actions__divider' action_btn.appendChild(divider) const download_btn = document.createElement('i') download_btn.className = 'el-icon' download_btn.innerHTML = ` ` const date = new Date() download_btn.addEventListener('click', () => { const fileName = binding.value[2] || `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}` downloadImgVideo(urls[downloadIndex], fileName) }) action_btn.appendChild(download_btn) }); }, unmounted(el) { el.removeEventListener('click', () => {}); } }); }