Vue+Element页面生成快照截图

页面部分:

html 复制代码
<template>
  <div ref="homePage" class="home-container rel">
    <div class="snap-box abs">
      <div title="页面快照" class="z-pointer" @click="newSnapShot()">
        <img :src="snapCamera" alt="快照生成">
      </div>
    </div>
    <el-image-viewer
      v-if="imgUrl"
      :on-close="()=>{imgUrl=''}"
      :url-list="[imgUrl]" />
  </div>
</template>

js代码部分:

javascript 复制代码
/**
 * 图片blob转图片base64
 * @param blob
 */
export const blobToBase64 = (blob) => {
	return new Promise((resolve, reject) => {
		const fileReader = new FileReader();
		fileReader.onload = (e) => {
			resolve(e.target.result);
		};
		// readAsDataURL
		fileReader.readAsDataURL(blob);
		fileReader.onerror = () => {
			reject(new Error('blobToBase64 error'));
		};
	});
}



import html2canvas from 'html2canvas';
import { blobToBase64 } from '@/utils/helper.js';


export default {
  name: 'Home',
  components: {
    'el-image-viewer': () => import('element-ui/packages/image/src/image-viewer'),
  },
  data() {
    return {
      tooltipRemark,
      loading: false,
      imgUrl: '',
    };
  },
  methods: {
    // 生成快照
    newSnapShot() {
      this.loading = true;
      const { ClipboardItem } = window;
      html2canvas(this.$refs.homePage).then((canvas) => {
        // 将canvas转为blob对象
        canvas.toBlob(async (blob) => {
          if (typeof (navigator.clipboard) === 'undefined' && !ClipboardItem) {
            await blobToBase64(blob).then((res) => {
              this.imgUrl = res;
              this.$message({
                message: '快照生成成功',
                type: 'success',
                duration: 2000,
              });
            }).catch(() => {
              this.$message({
                message: '快照生成失败',
                type: 'warning',
                duration: 2000,
              });
            }).finally(() => {
              this.loading = false;
            });
            return;
          }
          // 将blob对象放入剪切板item中
          // eslint-disable-next-line no-undef
          const data = [new ClipboardItem({ [blob.type]: blob })];
          // 写入剪切板,成功会执行resolve,失败则走reject
          await navigator.clipboard.write(data).then(() => {
            this.$message({
              message: '已保存到粘贴板',
              type: 'success',
              duration: 2000,
            });
            this.loading = false;
          }, () => {
            this.$message({
              message: '保存截图失败',
              type: 'warning',
              duration: 2000,
            });
            this.loading = false;
          });
        }, 'image/png');
      }).catch(() => {
        this.loading = false;
      });
    },
  },
};
相关推荐
MariaH几秒前
Git Cherry Pick 常用操作
前端
初圣魔门首席弟子6 分钟前
AI Agent 核心原理:工具调用(Function Calling)完整工作流程详解
前端·数据库·人工智能
CodeSheep12 分钟前
又是梁文锋,有点猛啊。
前端·后端·程序员
qq_4221525717 分钟前
视频转 GIF 工具怎么选?2026 年动图制作方案与画质参数对比
javascript·vue.js·音视频
陈老老老板23 分钟前
如何用 Bright Data Web Scraper API + Coze 搭建 Reddit 行业情报聚合 Bot(2026 实战指南)
前端·人工智能
恋猫de小郭30 分钟前
由于 iOS 26 的键盘变化,Flutter 又要重构键盘区域逻辑
android·前端·flutter
怕浪猫35 分钟前
Electron 开发实战(十五):实战项目|从零搭建桌面即时通讯(IM)应用
前端·javascript·electron
喜欢踢足球的老罗42 分钟前
破解 Chrome 扩展的「两世界难题」:MV3 下的 ISOLATED 与 MAIN World 桥接之道
前端·chrome
一拳一个娘娘腔43 分钟前
【第七期】漏洞攻防-前端篇:XSS 与 CSRF —— 当浏览器成为攻击者的“肉鸡”
前端·xss·csrf