react —— 复制定制化带有标题的二维码

1. 生成二维码直接借助qrcode这个npm库即可生成二维码,但接到的需求要求是在鼠标点击的附近展示出二维码,点击弹窗里面的复制按钮即可赋值带标题的二维码图片到剪切板,实现效果如下图:

 

主要实现要点:

1.利用qrcode 生成二维码;

2.蚂蚁金服组件气泡弹窗Popover,弹出点击位置弹窗;

3. 点击复制时,利用domimage这个npm包,直接将dom布局转化成图片;

4. base64图片转成blob对象,创建剪切板对象;

编写如下组件

import React, { useRef, useState, Fragment } from 'react';
import { Button, message, Popover } from 'antd';
import styles from './index.less';
import { base64ToBlob, copyToClipboard } from '@/utils/utils';
import QRcode from 'qrcode';
import domtoimage from 'dom-to-image';

interface dataProp {
  selectPaperTitle: string;
  url: string;
  menu: string;
}

const QrcodeMenu: React.FC<dataProp> = (props) => {
  const { selectPaperTitle, url, menu } = props;
  const [qrcodeUrl, setQrCodeUrl] = useState<string>(url);
  const imgDom = useRef<any>(null);
  const content = (
    <Fragment>
      <div ref={imgDom} className={styles.container}>
        <div className={styles.title}>{selectPaperTitle}</div>
        <img className={styles.img} src={qrcodeUrl} alt="链接二维码" />
      </div>
      <div className={styles.btncontainer}>
        <Button
          className={styles.btn}
          type="primary"
          onClick={() => {
            try {
              domtoimage.toPng(imgDom?.current).then((codeurl: string) => {
                copyToClipboard(base64ToBlob(codeurl));
                message.success('二维码复制成功');
              });
            } catch {
              message.error('二维码复制失败');
            }
          }}
        >
          复制
        </Button>
      </div>
    </Fragment>
  );
  return (
    <Popover
      onVisibleChange={async (visible: any) => {
        if (visible) {
          QRcode.toDataURL(url, { margin: 0, width: 160 }).then((res) => setQrCodeUrl(res));
        }
      }}
      autoAdjustOverflow={false}
      overlayClassName={styles.menu}
      placement="leftBottom"
      content={content}
      trigger={['hover']}
    >
      {menu}
    </Popover>
  );
};
export default QrcodeMenu;

2.复制到剪切板的功能实现:

utils.js文件

// 复制png图片到粘贴板
export function copyToClipboard(blob: Blob | null) {
  if (blob) {
    const clipboardItem: any = new ClipboardItem({ [blob.type]: blob });
    navigator?.clipboard?.write([clipboardItem]);
  }
}

/**
 * base64转blob
 */
export function base64ToBlob(urlData: string, type?: string) {
  const arr = urlData.split(',');
  const mime = arr[0]?.match(/:(.*?);/)?.[1] || type;
  // 去掉url的头,并转化为byte
  const bytes = window.atob(arr[1]);
  // 处理异常,将ascii码小于0的转换为大于0
  const ab = new ArrayBuffer(bytes.length);
  // 生成视图(直接针对内存):8位无符号整数,长度1个字节
  const ia = new Uint8Array(ab);
  for (let i = 0; i < bytes.length; i += 1) {
    ia[i] = bytes.charCodeAt(i);
  }
  return new Blob([ab], {
    type: mime,
  });
}

3. index.less

.container {
  padding: 16px;
  background: #fff;
  .title {
    margin-bottom: 16px;
    color: rgba(0, 0, 0, 0.85);
    font-weight: 400;
    font-size: 12px;
    font-family: PingFangSC-Regular, PingFang SC;
    line-height: 20px;
  }
  .img {
    display: block;
    margin: 0 auto;
  }
  .btn {
    display: block;
    margin: 0 auto;
  }
}
.btncontainer {
  text-align: center;
}
.menu {
  width: 240px;
  padding-right: 0;
  background: #fff;
  border-radius: 2px;
  box-shadow: 0 9px 28px 8px rgba(0, 0, 0, 0.05), 0 6px 16px 0 rgba(0, 0, 0, 0.08),
    0 3px 6px -4px rgba(0, 0, 0, 0.12);
  :global {
    .ant-popover-arrow {
      display: none;
    }
    .ant-popover-inner-content {
      height: auto;
      padding: 0 0 16px;
    }
  }
}

4. 引入方式:

<QrcodeMenu selectPaperTitle={r.title} menu={'二维码'} url={r.url} />

 


http://www.niftyadmin.cn/n/640684.html

相关文章

Kubelet bootstrap认证配置步骤

kubelet 授权 kube-apiserver 的一些操作 exec run logs 等 RBAC 只需创建一次就可以 kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrolesystem:kubelet-api-admin --user kubernetes 创建 bootstrap kubeconfig 文件 注意: token 生效时间为 1day…

vue——移动端在线预览pdf并能缩放(pdfh5)

最近接了一个需求需要在移动端预览pdf&#xff0c;并切要能缩放&#xff0c;百度发现大多推荐vue-pdf&#xff0c;但是vue-pdf这个包&#xff0c;安装之后运行报错&#xff0c;解决之后的实现效果不符合需求需要&#xff0c;而且&#xff0c;实现缩放功能的时候&#xff0c;整个…

Docker网络实现容器互联

一、新建docker网络命令 docker network create -d bridge 网络名称 二、docker网络实现容器互联实践 步骤1、在/data/dockerfile目录下&#xff0c;vim Dockerfile添加如下内容&#xff1a; FROM ubuntu:14.04 RUN apt-get install -y ping RUN apt-get update &&…

vue-pdf安装之后,运行报错can not resolve ‘pdfjs-dist/es5/web/pdf_viewer‘

安装方式&#xff1a; npm i --save vue-pdf ​​​​​​​1. 使用组件&#xff1a; <PreViewPdf ref"PreViewPdf"></PreViewPdf>this.$refs.PreViewPdf.openPdf(item.oss_url) 2. 项目抛出如下错误&#xff1a; 通过查阅vue-pdf的github项目的issue发…

leetCode 14 Longest Common Prefix

leetcode.windliang.cc/ 第一时间发布 题目描述&#xff08;简单难度&#xff09; 解法一 垂直比较 我们把所有字符串垂直排列&#xff0c;然后一列一列的比较&#xff0c;直到某一个字符串到达结尾或者该列字符不完全相同。 下边看一下我的代码&#xff0c;看起来比较多 //这个…

测试设计之等价类边界值

一、等价类分析定义 等价类划分技术把测试对象的输入域划分成若干部分&#xff0c;然后从每一部分中选取少数有代表性的数据&#xff0c;做为测试用例输入数据的测试用例设计技术&#xff1b;等价类是指测试对象某个参数输入域的子集合。在该子集合中&#xff0c;各个输入数据…

react——利用jszip实现文件批量下载并打包成zip文件

本文章主要记录利用jszip实现文件批量下载图片&#xff0c;文档。mp3&#xff0c;视频&#xff08;MP4)等文件&#xff0c;一般而言前端实现下载功能一般都是通过a链&#xff0c;这在下载单个文件的场景很实用&#xff0c;但如果是批量下载很多个文件&#xff0c;同样也可以用a…

【docker】docker 搭建 mongodb3.6,开启授权访问

首先下载mongodb3.6镜像&#xff1a; docker pull mongo:3.6mongodb通常占用27017端口&#xff0c;最简单的启动方式如下&#xff1a; docker run --name mongodb -p 27017:27017 -d mongo:3.6不过通常情况下&#xff0c;我们不会直接这样启动。我们需要绑定数据卷&#xff0c;…