Vue自动生成二维码并可下载二维码

news2025/1/14 18:06:26

        遇到一个需求,需要前端自行生成用户的个人名片分享二维码,并提供二维码下载功能。在网上找到很多解决方案,最终吭哧吭哧做完了,把它整理记录一下,方便后续学习使用!嘿嘿O(∩_∩)O~

这个小东西有以下功能特点:

1.可以生成密密麻麻程度不一样的二维码

2.可以生成不同颜色的二维码

3.二维码支持下载

4.代码简洁且通俗易懂(小白只能这样啦!)

        首先,先记录一下我的实验版本,因为怕把项目搞砸,所以我就自己create一个单独的小demo来实验,等功能实现了再搬过去用。系不系很机智!!!

一、实验小Demo

1、点击获取二维码

<template>
 <div class="click-code">
 <div class="click-code-pic">
   <img class="logo" :src="src">
  </div>
 <div class="click-code-info">
     <h6>{{title}}</h6>
     <p>{{text}}</p>
     <button @click="getCode(1)">点击获取二维码</button>
     <div class="isShow" v-if="isClick==1">
      <div class="img-box">
          <!-- 这里一定要记得写绑定,一开始一直弹不出来,最后才发现是没绑定!!! -->
          <JkQrcode :url="url" :color="color" :margin="margin" class="cover-img"/>
          <span class="image-remove" @click="getCode(0)">+</span>               
      </div>
     </div>
     </div>
 </div>
</template>

<script>
import JkQrcode from'./JkQrcode'

export default {
  name: 'ClickCode',
   components: {
     JkQrcode,
  },
  data() {
     return {
      isClick: 0,
      title:'你好呀!',
      text:'点击下方按钮获取二维码',
      width: 500,
      margin: 1,
      src:require('../assets/logo.png') ,
      url:'',
      color:'#'
     };
 },
 methods:{
     getCode(a){
      if(a==1){
        this.isClick=1;
        // 生成不同的二维码(在实际项目中,这些信息是通过后端返回的信息来绑定的,而不是这样随机生成啥就是啥) 
        let arr = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
        "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
        "0","1","2","3","4","5","6","7","8","9"];
        // //生成不同的颜色  
        let lit=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
        // 为了降低重复率,多几个拼接,发现循环次数越多,二维码越密密麻麻
        for(let i=0;i<16;i++){
            this.url+=arr[Math.floor(Math.random()*36)];
        }
        // this.url="http://"+this.url+".png";
        for(var j=0;j<3;j++){
            this.color+=lit[Math.floor(Math.random()*16)];
        }
        var HisUrl=this.url;
        var HisCol=this.color;
      }
      if(a==0){
        if(!confirm("关闭后二维码将刷新,是否确定关闭?"))
        {
          this.url=HisUrl;
          this.color=HisCol;
        }
        else{
          this.isClick=0;
          // 这里一定要初始化,不然它会一只连接下去,越来越长越来越长
          this.url="";
          this.color="#";
        }
      }
  }
 }
}
</script>

<style>
button{
  width:150px;
  height:50px;
  position: absolute; 
}
.img-box{
  display: inline-block;  
  border: 1px solid #ececec;
  position: relative;
}
.cover-img{
  max-width: 800px;
  min-width: 200px;
}
.image-remove{
  background-color: white;
  font-color: #ececec;
  font-size: 30px;
  width: 30px;
  height: 30px;
  text-align: center;
  border-radius: 100%;
  transform: rotate(45deg); 
  cursor:pointer;
  opacity: 0.5;
  top:2px;
  right:2px;   
  display: block; 
  position: absolute; 
}
.isShow{
  display: true;
  position: absolute; 
  top: 10%; 
  left: 15%; 
  /* opacity属性指定了一个元素后面的背景的被覆盖程度。【设置透明度:越低越透明】*/
  opacity: .90; 
}
.logo{
  width: 200px;
  height: 200px;
  border-radius: 15px;
}
.click-code {
 display: flex;
 height: 200px;
 border: 3px solid #999;
 padding: 20px;
 border-radius: 21px;
  &-pic {
    display: flex;
    flex-direction: column;
    justify-content: center;
     img {
     height: 100%;
     }
 }
 &-info {
 display: flex;
 flex-direction: column;
 justify-content: center;
 h6 {
 font-size: 46px;
 }
 p {
 font-size: 36px;
 margin-top: 20px;
 }
 }
}
</style>




2、点击下载二维码

<template>
  <div class="qrcode-box">
    <img :src="imgUrl" alt="二维码图片"/><br/>
    <!-- 一开始写在ClickCode,一直获取不到图片,写在这里面就可以顺利找到图片地址了 -->
    <button @click="downloadCodeImg" >点击下载二维码</button> 
  </div>
</template>

<script>
import QRCode from 'qrcode'

export default {
  name: 'JkQrcode',
  props: {
    url: {
      type: String,
      default: ''
    },
    color: {
      type: String,
      default: '#000'
    },
    width: {
      type: Number,
      default: 200
    },
    margin: {
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      imgUrl: ''
    }
  },
  watch: {
    url() {
      this.createQRCode()
    }
  },
  mounted() {
    this.createQRCode()
  },
  methods: {
    createQRCode() {
      if (!this.url) return
      QRCode.toDataURL(this.url, {
        errorCorrectionLevel: 'H',
        color: { dark: this.color, light: '#fff' },
        width: this.width,
        margin: this.margin
      })
        .then(url => {
          this.imgUrl = url
        })
        .catch(err => {
          console.error(err)
        })
    },
    //https://blog.csdn.net/sumimg/article/details/102969740 //下载二维码
     downloadCodeImg(){
     let link = document.createElement('a')
     let url =  this.imgUrl//要下载的路径
     // 这里是将url转成blob地址,
     fetch(url).then(res => res.blob()).then(blob => { //将链接地址字符内容转变成blob地址
         link.href = URL.createObjectURL(blob)
         console.log(link.href)
         link.download ='QrCode'
         document.body.appendChild(link)
         link.click()
     })
  }
  }
}
</script>
<style>
button{
  width:150px;
  height:50px;
  position: absolute; 
}
.qrcode-box {

}
</style>

3、使用组件

<template>
  <clickCode/>
</template>

<script>
import ClickCode from './components/ClickCode'

export default {
  name:'App',
  components: {
    ClickCode
  }
}
</script>

4、效果

 

二、在小程序项目中使用(用Canvas)

在这里,二维码的大小是自适应的

qrwidth: 200 / 750 * wx.getSystemInfoSync().windowWidth,

1、使用入口

<view><button class="edit-btn" @tap="handleShareCard">分享名片</button></view>
<canvas v-show="showQrcode" class="canvas-qcode" canvas-id="qrcanvas" :style="'width:' + qrwidth + 'px;height:' + qrwidth + 'px;'"></canvas>
<canvas class="temp-canvas" canvas-id="tempCanvas" style="position: absolute; left: -10000px; top: 10000px;" :style="'width:' + qrwidth + 'px;height:' + qrwidth + 'px'"></canvas>

 2、生成唯一的二维码

      const text = getApp().globalData.QCODE_URL + (_self.company.tyshxydm || "") + "&companyName=" + _self.company.jgmc
      drawQrcode({
        width: _self.qrwidth,
        height: _self.qrwidth,
        foreground: _self.qrColor,
        canvasId: "qrcanvas",
        text,
        image: {},
        callback: res => {}
      });
      // 在名片中这么处理,在详情页不需要处理中间图片
      drawQrcode({
        width: _self.qrwidth,
        height: _self.qrwidth,
        foreground: '#000',
        canvasId: "tempCanvas",
        text: text + "&companyMobile=" + _self.userInfo.mobile,
        callback: res => {
          // 读取二维码,并绘制二维码
          _self.canvasToImg({
            canvasId: "tempCanvas",
            width: _self.imageWidth,
            height: _self.imageWidth * 0.6,
            callback(res) {
              console.info("canvasToImg", res.tempFilePath);
              _self.canvasImg = res.tempFilePath;
            }
          });
        }
      });

3、保存

    // 保存名片
    onTapSaveCard(e) {
      let _self = this;
      _self.canvasToImg({
        canvasId: "cardCanvas",
        width: _self.imageWidth,
        height: _self.imageWidth * 0.6,
        callback(res) {
          debugger
          _self.saveImg(res.tempFilePath);
        }
      });
    },

 因为不能泄露公司的一些业务,就只放一些核心代码就好啦!~

总而言之,导师说用canvas绘制会性能更好些。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1008627.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深入解读Redis系列】(五)Redis中String的认知误区,详解String数据类型

有时候博客内容会有变动&#xff0c;首发博客是最新的&#xff0c;其他博客地址可能会未同步&#xff0c;请认准https://blog.zysicyj.top 首发博客地址 系列文章地址 需求描述 现在假设有这样一个需求&#xff0c;我们要开发一个图像存储系统。要求如下&#xff1a; 该系统能快…

QT QAxWidget控件 使用详解

本文详细的介绍了QAxWidget控件的各种操作&#xff0c;例如&#xff1a;新建界面、使用示例、显示网页、显示pdf、显示Off、源文件详细说明其它文章等等操作。 ActiveX控件是一种可重用的二进制组件&#xff0c;用于在Windows操作系统上提供特定的功能和服务。以下是一些常见的…

python pycharm 下载 安装 自(1)

pycharm 官网 JetBrains: 软件开发者和团队的必备工具 python 官网 Python Release Python 3.11.5 | Python.org 软件安装 因为python需要借助pycharm所以需要安装 下边截图是重要的部分 pycharm python 终端安装 然后进行全局配置 打开pycahrm 可以在扩展里边搜索中…

后端字典的优雅设计

背景 今天讲到的是数据字典的设计。为什么要讲到这个呢&#xff0c;因为我下午在做开发的时候遇到了一个问题。我先扔出来某个表的字段的定义吧&#xff1a; business_type int default 0 comment 0&#xff1a;收款计划&#xff1b;1&#xff1a;付款计划而且我还有一个字典…

【2023年11月第四版教材】第12章《质量管理》(合集篇)

第12章《质量管理》&#xff08;合集篇&#xff09; 1 章节说明2 管理基础3 管理过程3.1 管理ITTO汇总★★★ 4 规划质量管理4.1 数据收集★★★4.2 数据分析★★★4.3 数据表现★★★4.4 质量管理计划★★★4.5 质量测量指标★★★ &#xff08;22下35&#xff09; 5 管理质量…

SpringMVC系列(六)之JSON数据返回以及异常处理机制

目录 前言 一. JSON概述 二. JSON数据返回 1. 导入pom依赖 2. 添加配置文件&#xff08;spring-mvc.xml&#xff09; 3. ResponseBody注解使用 4. 效果展示 5. Jackson介绍 三. 全局异常处理 1. 为什么要全局异常处理 2. 异常处理思路 3. 异常处理方式一 4. 异常处…

算法--插入排序

算法步骤 /*** 插入排序** version 1.0* date 2023/09/01 18:48:44*/ public class Insert {/*** 升序插入排序** param a 待排序的数组* date 2023/9/1 15:29:10*/public static void sortAes(int[] a) {int length a.length;for (int i 1; i < length; i) {for (int j …

Jmx协议远程连接java服务器

注意&#xff1a;本例里&#xff0c;我用的是jdk17 通常用jdk自带的jconsole&#xff0c;或者想要功能强大点的使用visualVM 需要java服务器在启动的时候加上以下参数 -Dcom.sun.management.jmxremote 启用jxm远程连接-Djava.rmi.server.hostname10.1.3.99 指定jxm监听地址&…

《向量数据库指南》——“插件版”向量数据库与Milvus Cloud原生向量数据库之间的区别?

我一直坚持一个观点&#xff0c;即并非所有基于向量的解决方案都应被统称为向量数据库&#xff0c;尽管它们的能力在某些方面可以与之匹敌。从我的观点来看&#xff0c;例如 pgvector 或 Elasticsearch&#xff0c;它们都是非常出色且成熟的产品&#xff0c;在特定场景下&#…

【C语言】扫雷小游戏(保姆教程)

目录 一、扫雷游戏介绍 二、代码分装 三、代码实现步骤 1. 制作菜单menu函数以及游戏运行逻辑流程 2. 数组棋盘分析 3. 创建棋盘数组 4. 初始化棋盘InitBoard函数 5. 显示棋盘DisplayBoard函数 6. 布置雷SetMine函数 7. 统计雷个数GetMineCount函数 8. 排查雷FindMine函…

手摸手系列之前端Vue实现PDF预览及打印的终极解决方案

前言 近期我正在开发一个前后端分离项目&#xff0c;使用了Spring Boot 和 Vue2&#xff0c;借助了国内优秀的框架 jeecg&#xff0c;前端UI库则选择了 ant-design-vue。在项目中&#xff0c;需要实现文件上传功能&#xff0c;同时还要能够在线预览和下载图片和PDF文件&#x…

【C# Programming】继承、接口

一、继承 1、派生 继承在相似而又不同的概念之间建立了类层次概念。 更一般的类称为基类&#xff0c;更具体的类称为派生类。派生类继承了基类的所有性质。 定义派生类要在类标识符后面添加一个冒号&#xff0c;接着添加基类名。 public class PdaItem {public string Name {…

java的入门学习

1. 安装jdk 一般是安装java8&#xff0c;大部分使用的版本是java8&#xff1b; 然后需要部署java环境变量 2. 编译class文件 javac 文件名.java 3. 执行class文件 编译命令为java 文件名 配置classpath路径为.\为当前路径下的class文件名 4. 变量 成员变量&#xff1a;类…

Pycharm中配置Celery启动

Pycharm中配置Celery启动 前置条件 目录结构 ----FerDemo --------celery_demo ------------tasks.py tasks.py文件代码 import sys import time from celery import Celeryapp Celery(demo,backendredis://:password127.0.0.1/0,brokerredis://:password127.0.0.1/1,broker…

【线性代数】沉浸式线性代数在线学习网站

地址&#xff1a;http://immersivemath.com/ila/index.html 这是全球第一本带交互式图形的线性代数教材&#xff0c;作者是 J. Strm, K. strm, and T. Akenine-Mller。 全书一共十章&#xff0c;各章节内容如下&#xff1a; 接下来我将对各章节进行简单的总结&#xff0c;另外…

LLM - SFT workflow 微调工作流程

目录 一.引言 二.Workflow 分流程拆解 1. Workflow 代码 2.Workflow 拆解 ◆ 超参数初始化 ◆ 数据集初始化 ◆ 加载与量化 ◆ 数据集预处理 ◆ DataCollator ◆ 模型微调 sft 三.总结 一.引言 前面我们对 LLM 相关流程的单步都做了分析…

Linux入门教程||Linux文件基本属性

Linux系统是一种典型的多用户系统&#xff0c;不同的用户处于不同的地位&#xff0c;拥有不同的权限。为了保护系统的安全性&#xff0c;Linux系统对不同的用户访问同一文件&#xff08;包括目录文件&#xff09;的权限做了不同的规定。 在Linux中我们可以使用 ll 或者 ls –l…

分类预测 | Matlab实现RBF-Adaboost多特征分类预测

分类预测 | Matlab实现RBF-Adaboost多特征分类预测 目录 分类预测 | Matlab实现RBF-Adaboost多特征分类预测效果一览基本介绍研究内容程序设计参考资料 效果一览 基本介绍 1.Matlab实现基于RBF-Adaboost数据分类预测&#xff08;Matlab完整程序和数据&#xff09; 2.多特征输入…

有关Monaco LSP的集成 monaco-languageclient 项目的开启

要求 node 18x npm 9x git clone https://github.com/TypeFox/monaco-languageclient.git cd monaco-languageclient npm i# Cleans-up, compiles and builds everything npm run build npm run dev # 访问 http://127.0.0.1:8080/两个自动完成&#xff0c; 两个验证 纠错

马蹄集 oj赛(第十一次)

目录 除法2 tax 约数个数 约数之和 全部相同 石头剪刀布 模数 余数之和 数树 除法 除法2 黄金时间限制:1秒占用内存: 128 M难度: 给定n&#xff0c;求 ”i*[n/]&#xff0c;[] 表示对 取下整 格式 一个正整数n。输入格式: 输出格式:一个数表示答案 样例1 输入:4 输出…