vue3实现一个抽奖小项目

前言

  • 在公司年会期间我做了个抽奖小项目,我把它分享出来,有用得着的可以看下。
  • 浏览链接:http://xisite.top/original/luck-draw/index.html
  • 项目链接:http://gitee.com/xi1213/luck-draw (欢迎star!)
  • 项目截图:

实现目标

  • 数据保存:无后端,纯前端实现,浏览器刷新或者关闭数据不能丢失。
  • 姓名切换:点击中部开始按钮姓名快速切换。
  • 奖项切换:奖项为操作人员手动切换设置。
  • 历史记录:抽奖完成后需要有历史记录。
  • 数据导入:允许参与人员的表格导入。

数据保存

无后台,纯前端实现而且需要刷新关闭浏览器数据不丢失,很容易便会想到使用localStorage,localStorage存入的数据具有持久性,不会因为刷新或关闭浏览器而变化(除非手动刻意的清除),有别于sessionstorage,localStorage的生命周期是永久,sessionstorage是浏览器或者标签页关闭。

因为存入的数据不是单纯的字符串,而是具有结构性的对象数组,所以需要配合JSON.stringify与JSON.parse来使用。这是存入数据的方法:

localStorage.setItem("luckDrawHis", JSON.stringify(luckDrawHis));//JSON.stringify将json转换为字符串

这是读取数据的方法:

JSON.parse(localStorage.getItem("luckDrawHis"))//JSON.parse将字符串转换为json

姓名切换

抽奖的方式是数据导入后,点击中间的圆形开始按钮,姓名便开始快速切换,再次点击按钮便停止姓名切换,弹出对话框显示当前姓名以及设置的奖项。

切换姓名利用了vue的数据响应式原理。先获取到所有的参与人员数据,然后乱序处理,最后循环展示,我这里每个姓名展示的时间为50毫秒,你也可以自己设置。这里的数组乱序我使用了洗牌算法,其实就是利用Math.random获取数组的随机下标,然后与最后一个元素进行位置交换。

//洗牌算法(乱序数组)
function shuffle(arr) {
  let l = arr.length
  let index, temp
  while (l > 0) {
    index = Math.floor(Math.random() * l)
    temp = arr[l - 1]
    arr[l - 1] = arr[index]
    arr[index] = temp
    l--
  }
  return arr;
}

//循环列表
function forNameList(list) {
  list = shuffle(list);
  for (let i = 0; i < list.length; i++) {
    setTimeout(() => {
      if (!isStop.value) {
        curName.value = list[i].name;
        (i == list.length - 1) && (forNameList(nameList.value));//数组耗尽循环
      }
    }, 50 * i);
  }
}

奖项切换

奖项切换直接使用elementPlus的单选框即可。

历史记录

每次点击抽奖出现结果时,将之前的抽奖结果取出来,然后把当前的结果添加到末尾。

点击抽奖历史按钮时再将所有历史数据取出来。

数据导入

由于需要导入人员表格数据,这里我使用了xlsx插件与file-saver插件来实现。

首先是下载模板。
在这里插入图片描述

将事先准备好的表格模板放在项目的public目录下。

点击下载模板按钮时直接调用以下方法即可,其中的saveAs是file-saver插件中的方法,传入路径与文件名即可。

import { saveAs } from 'file-saver';
//下载模板
function downTemp() {
    let fileName = "人员模板.xlsx";//文件名
    let fileUrl = "./template/";//文件路径(路径相对index.html)
    saveAs(fileUrl + fileName, fileName);
}

表格处理好,

点击导入按钮读取表格数据时使用的是xlsx插件,下面是读取数据的方法。

import * as XLSX from "xlsx";
//导入数据
function importData(e) {
    isLoading.value = true;
    let file = e.target.files[0]; //获取事件中的file对象
    let fileReader = new FileReader(); //创建文件读取器
    fileReader.onload = (event) => {
        let result = event.target.result; //获取读取的结果
        let workBook = XLSX.read(result, { type: "binary" }); //XLSX读取返回的结果
        let jsonData = XLSX.utils.sheet_to_json(
            workBook.Sheets[workBook.SheetNames[0]]
        ); //将读取结果转换为json
        tabData.value = [];
        jsonData.forEach((j) => {
            tabData.value.push({
                name: j.姓名,
                age: j.性别,
                department: j.部门,
            });
        }); //处理成需要的数据格式
        localStorage.setItem("tabData", JSON.stringify(tabData.value));//数据存入本地
        tabDataS.value = JSON.parse(localStorage.getItem("tabData"));//取出数据
        emits("getNameList", tabData);
        isLoading.value = false;
    };
    fileReader.readAsBinaryString(file); //开始读取文件
    ((document.getElementsByClassName("inp-xlsx")[0]).value = ""); //置空选中的文件
};

结语

  • 项目很简单,但给我的时间很少,很多优化的地方都没做好,后面有时间了再优化下,顺便适配下移动端。
  • 原文地址:http://xiblogs.top/?id=53

原创者:曦12

原文链接:http://www.cnblogs.com/xi12/p/17062917.html

转载请注明原创者添加原文链接!

本文转载于网络 如有侵权请联系删除

相关文章

  • 线程池参数调优「建议收藏」

    大家好,又见面了,我是你们的朋友全栈君。ThreadPoolExecutorThreadPoolExecutor构造函数的五大参数publicThreadPoolExecutor(intcorePoolSize, intmaximumPoolSize, longkeepAliveTime, TimeUnitunit, BlockingQueue<Runnable>workQueue){ this(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue, Executors.defaultThreadFactory(),defaultHandler); }复制corePoolSize核心线程数,表示线程池支持的最小线程数maximumPoolSize最大线程数,当线程数大于核心线程数后,并且有界队列里存放能时,线程池还能接受maximumPoolSize–corePoolSize个线程keepAliveTime保持存活时间,空闲线程的存活时间,为了更好的复用线程unit线程存活时间的单位workQueue队列,等待

  • 腾讯云TDP-virt-viewer win客户端的软件使用

    腾讯云TDP-virt-viewerwin客户端的软件使用简介1.使用此软件可以交付给用户,对VM单台实例,开关机、发送组合键的权限2.使用此软件可以解决KVM宿主机内virt-manager客户端操作单台VM时,鼠标跟踪不同步问题3.使用此软件可以映射本地的设备到VM,如摄像头、麦克风、加密狗4.此功能相当于在腾讯云CVM控制台点击登录,选择单台CVM的VNC管理配置VM启用spice协议根据自己的KVM宿主机的网络和端口情况,修改spice监听的地址和端口即可下载和使用virt-viewer软件官网地址https://virt-manager.org/download/下载适用于Windows系统的virt-viewer软件https://virt-manager.org/download/sources/virt-viewer/virt-viewer-x64-11.0-1.0.msi相关文章参考链接Ubuntu1604下使用qemu+kvm搭建spice虚拟化云ZstackSpice和QXL设置Windows系统使用RemoteFx重定向USB设备使用VNC登录Windows实例

  • Linux 下载文件报 Let's Encrypt R3 证书过期

    使用wget下载文件时,报了一个错误,浏览器打开检查证书,发现证书没过期。联想起前段时间Let'sEncrypt更换了根证书,那应该就是这个问题了。报错信息:#wgethttps://dl.ll00.cn/v2ray-linux-64.zip --2021-11-0311:55:26--https://dl.ll00.cn/v2ray-linux-64.zip Resolvingdl.ll00.cn(dl.ll00.cn)...59.83.218.168,116.178.66.14,59.80.39.21,... Connectingtodl.ll00.cn(dl.ll00.cn)|59.83.218.168|:443...connected. ERROR:cannotverifydl.ll00.cn'scertificate,issuedby‘/C=US/O=Let'sEncrypt/CN=R3’: Issuedcertificatehasexpired. Toconnecttodl.ll00.cninsecurely,use`--no-check-ce

  • Java super继承

    参考链接:Javasupersuper关键字 super的用法和this很像 this代表本类对应的引用。super代表父类存储空间的标识(可以理解为父类引用)用法(this和super均可如下使用) 访问成员变量this.成员变量super.成员变量 访问构造方法(子父类的构造方法问题讲)this(…)super(…) 访问成员方法(子父类的成员方法问题讲)this.成员方法()super.成员方法() 子类中所有的构造方法默认都会访问父类中空参数的构造方法: 因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化每一个构造方法的第一条语句默认都是:super()继承中构造方法的关系 如果父类中没有构造方法 子类通过super去显示调用父类其他的带参的构造方法子类通过this去调用本类的其他构造方法本类其他构造也必须首先访问了父类构造 super(…)或者this(….)必须出现在第一条语句山否则,就会有父类数据的多次初始化 例子: classFather{      publicFather(){         System.out

  • 从根上理解高性能、高并发(七):深入操作系统,一文读懂进程、线程、协程

    本文引用了“一文读懂什么是进程、线程、协程”一文的主要内容,感谢原作者的无私分享。1、系列文章引言1.1文章目的作为即时通讯技术的开发者来说,高性能、高并发相关的技术概念早就了然与胸,什么线程池、零拷贝、多路复用、事件驱动、epoll等等名词信手拈来,又或许你对具有这些技术特征的技术框架比如:Java的Netty、Php的workman、Go的gnet等熟练掌握。但真正到了面视或者技术实践过程中遇到无法释怀的疑惑时,方知自已所掌握的不过是皮毛。返璞归真、回归本质,这些技术特征背后的底层原理到底是什么?如何能通俗易懂、毫不费力真正透彻理解这些技术背后的原理,正是《从根上理解高性能、高并发》系列文章所要分享的。1.2文章源起我整理了相当多有关IM、消息推送等即时通讯技术相关的资源和文章,从最开始的开源IM框架MobileIMSDK,到网络编程经典巨著《TCP/IP详解》的在线版本,再到IM开发纲领性文章《新手入门一篇就够:从零开发移动端IM》,以及网络编程由浅到深的《网络编程懒人入门》、《脑残式网络编程入门》、《高性能网络编程》、《不为人知的网络编程》系列文章。越往知识的深处走,越觉得对即

  • 1500+星标,简单易用 TensorFlow 代码集,随查随看!

    来源:Github编译:JunhoKim转载自:机器学习算法与自然语言处理,未经允许不得二次转载学习过机器学习和深度学习的小伙伴不可能不知道TensorFlow。它拥有多层级结构,可部署于各类服务器、PC终端和网页并支持GPU和TPU高性能数值计算,被广泛应用于谷歌内部的产品开发和各领域的科学研究。但却因难以上手将很多人阻档在外。最近来自韩国的AI研究科学家JunhoKim做了一份易于使用的TensorFlow代码集,目前该项目包含一般深度学习架构所需要的代码,例如初始化和正则化、各种卷积运算、基本网络架构与模块、损失函数和其它数据预处理过程。此外,作者还特别增加了对GAN的支持,这主要体现在损失函数上,其中生成器损失和判别器损失可以使用推土机距离、最小二乘距离和KL散度等。本份资料Github地址: https://github.com/taki0112/Tensorflow-Cookbook并且这份资料作者一直在更新。主要来说,资料分为以下几个部分:1.如何使用2.卷积3.Deconvolution4.Block5.归一化6.损失

  • 东京大学研究人员使用人工智能来预测放射性碎片的扩散

    AiTechYun编辑:chux在像2011年福岛那样的核熔毁之后,风和水流将放射性碎片广泛传播,使这些范围内的暴露风险。现有的大气建模工具非常不可靠,因此灾难应对小组很难确定人群撤离的优先顺序。幸运的是,东京大学的新研究表明,在机器学习的帮助下,可以准确预测放射性物质的分散。东京大学研究所的研究小组在ScientificReports期刊上发表的一项新研究报告中,提出了克服这一困难的方法。由TakaoYoshikane领导的团队,一位专门研究区域地球系统建模的项目讲师和发表在科学报告期刊上的论文的主要作者,在多年的天气模式数据上训练了神经网络,以预测放射性排放可能采取的路线。这一计算机程序,可以使用预期风力模式的天气预报,准确预测最终放射的放射性物质将在30小时内沉降的位置。该工具可以实施疏散计划和其他健康保护措施。令人印象深刻的是,当团队调整冬季天气模式的参数时,该模型预测扩散至少85%的准确度提升到95%。AI模型预测放射性物质的传播“在预测未来30多个小时时,这种方法的准确性并未降低,这在灾难情景中非常重要,”Yoshikane表示,“这使当局有时间在受影响最严重的地区安排疏散

  • Python 基础 模块

    python中模块和保定概念  如果将代码分才投入多个py文件,好处:    同一个变量名也互不影响。python模块导入    要使用一个模块,我们必须先导入该模块。python使用import    语句导入一个模块,例如导入系统自带的模块      impoormath      你可以认为math就是一个指向已导入模块的变量,通过该变量,      我们可以访问math模块中所定义的所有公开的函数、变量和类:    如果我们只希望导入用到的math模块的某几个函数,而不是所有函数,    可以用下面的语句:      frommathimportpow,sin,log      这样,可以直接引用 pow,sin,log 这3个函数,但math的其他函      数没有导入进来:    如果使用import导入模块名,由于必须通过模块名引用函数名,因此不存在      冲突:        importmath,logging          printmath.log(10)#调用的是math的log函数          logging.log(10,'some

  • POJ2253 && ZOJ1942

    两种写法用floyd算法,求所有点之间的最大跳的最小值,最后输出a[0][1],即起始与终止位置的最小值,采用传递闭包的思路,时间复杂度较高,但代码简单。或者Dijkstru的变形,两点间的最短距离,只是最短距离的求法有变,当前加入一个点时,松弛方法不同,时间复杂度降低了。在数据结构编程实验一书上,看到二分的写法,感觉很巧妙。也是把三种写法都看一下,前两种为找到的代码,最后一种是自己写的。floyd #include<stdio.h> #include<math.h> #defineN205 doublea[N][N]; intn,x[N],y[N]; doubledist(inti,intj) { returnsqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); } doublemax(doublex,doubley) { returnx>y?x:y; } doublemin(doublex,doubley) { returnx>y?y:x; } voidfloyd() { inti,j,k;

  • 腾讯云日志服务删除索引配置api接口

    1.接口描述接口请求域名:cls.tencentcloudapi.com。 本接口用于删除日志主题的索引配置,删除索引配置后将无法检索和查询采集到的日志。 默认接口请求频率限制:20次/秒。 APIExplorer提供了在线调用、签名验证、SDK代码生成和快速检索接口等能力。您可查看每次调用的请求内容和返回结果以及自动生成SDK调用示例。 2.输入参数以下请求参数列表仅列出了接口请求参数和部分公共参数,完整公共参数列表见公共请求参数。 参数名称 必选 类型 描述 Action 是 String 公共参数,本接口取值:DeleteIndex。 Version 是 String 公共参数,本接口取值:2020-10-16。 Region 是 String 公共参数,详见产品支持的地域列表。 TopicId 是 String 日志主题ID 3.输出参数 参数名称 类型 描述 RequestId String 唯一请求ID,每次请求都会返回。定位问题时需要提供该次请求的RequestId。 4.示例示例1删除索引配置输入示例POST

  • 在共有文件夹中删除某个人的权限的方法

    1.能看到文件夹本身,但是不能访问 セキュリティ⇒編集⇒选中要设置的某个用户⇒拒否のcheckbox行中选中以下两项 適用⇒OK⇒OK 2.看不到文件夹本身 方法① セキュリティ⇒編集⇒选中要设置的某个用户⇒拒否のcheckbox行中选中以下选项 適用⇒OK⇒OK 方法② セキュリティ⇒詳細設定⇒选中要设置的某个用户⇒継承の無効化⇒ 选上面的(选下面的将对一览中所有用户进行设置)⇒ 下面的checkbox选中的话此文件夹的子文件夹讲继承此属性 ⇒適用⇒はい⇒OK  

  • mybatis中xml字段空判断及模糊查询

    由于业务特殊的查询需求,需要下面的这种查询,一直感觉模糊不清,本地测试一下顺便做个总结 贴一段xml代码,如下: 1<iftest="receivedName!=nullandreceivedName!=''"> 2ANDreceivedName=#{receivedName} 3</if> 4<iftest="receivedName==null"> 5ANDreceivedNameisnull 6</if>复制 注意下面几点: 1、如果java代码中有receiveName这个参数且receiveName="jack",那么这种情况是满足上面第一种情况的,到mybatis中,转换sql语句就是“select*fromtablewherereceivedName="jack";”;2、如果java代码中有receivedName这个字段且receivedName="",那么这种情况是不满足上面的两个条件的,到mybatis中,转换sql语句就是“select*fromtablewhere1=1;”3、如果java代码中没有recei

  • Java第四十二天,会话内容(二),Cookie(一)

    一、概念 客户端会话技术,将数据保存到客户端 二、使用 1.设置cookie importjavax.servlet.ServletException; importjavax.servlet.annotation.WebServlet; importjavax.servlet.http.Cookie; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjava.io.IOException; @WebServlet(urlPatterns={"/first"}) publicclassFirstServletextendsHttpServlet{ @Override protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,

  • 【转】JAVA的静态变量、静态方法、静态类

    转自:http://blog.csdn.net/zhandoushi1982/article/details/8453522/    静态变量和静态方法都属于静态对象,它与非静态对象的差别需要做个说明。 (1)Java静态对象和非静态对象有什么区别?      比对如下:                                         静态对象              

  • centos6.9下php7安装zip扩展

    cd/usr/local/src wget http://pecl.php.net/get/zip-1.13.5.tgz   tar -zxvf zip-1.13.5.tgz   cd zip-1.13.5  /opt/remi/php70/root/usr/bin/phpize#根据自己安装的路径变更 ./configure--with-php-config=/opt/remi/php70/root/usr/bin/php-config  #根据自己安装的路径变更 make  maketest makeinstall 如果没有报错这样就安装完成了,用命令查看一下看有没有zip.so ls/opt/remi/php70/root/usr/lib64/php/modules/ 最后在php.ini里修改以下两项 1)zlib.output_compression=Off改为zlib.output_compression=On 2)增加extension=/opt/rem

  • react ant-menu-item-selected选中的菜单样式修改

    之前引入的方式是 importstylesfrom'./index.less'; 复制 然后我在index.less里修改,没有一点反应,后来发现上面引入的方式只是把样式导进去,用不用不清楚,这个时候需要加上 import'./index.less'; 复制 然后index.less里面的样式就可以生效了 .ant-menu-dark.ant-menu-dark:not(.ant-menu-horizontal).ant-menu-item-selected{ background-color:#2970FF; } 复制

  • 「游记」AtCoder Beginner Contest 209

    才4题(E题不知道错哪了),不过涨了500+Rating灰名->褐名 A-Counting sbt B-Canyoubuythemall? sbt C-NotEqual 排个序然后sbt D-Collision 很显然就是问两点之间距离的奇偶性,打了个树剖求lca就过了 自此花费了17分55秒 E-Shiritori 赛时我是利用map把字符串对应一个整数,再用vector存字符串对应的点之间的边,跑了个记搜。不知道为什么一直错5个点。。。一直到比赛结束(甚至到现在)都没有找出问题所在。 题解类似广搜的想法,已经在队列里的不再重复加入。其他地方貌似跟我一样。所以我到底错哪了QwQ F-Deforestation 赛时被E题弄的没有时间了。。。考虑每个高度\(H_i\)对答案的贡献,想到\(O(n^3)\)的DP。 前缀和优化一下\(O(n^2)\)。

  • 初识java

    Java的优点: Java是当今流行的面向对象编程语言,它具有良好的平台移植性和代码的开源性优点,因此我们小组决定采用Java语言作为我们项目的开发语言。Java语言具有以下的特点: 1.简单 2.面向对象 3.分布式 4.解释型 5.健壮 6.安全 7.与体系结构无关 8.可移植 9.高性能 10.多线程和动态执行 开始自学Java: 由于我前期只学过C语言,没有接触过Java语言,因此我需要从头学起,但有关Java语言的教材相当的多,于是我就借了一本清华大学出版社出版的《Java面向对象程序设计》,由于是大学教材,因此这本正是适合我这种Java零基础的人阅读,我按照课本第一章的提示编写了第一个Java程序——HelloWorld,尽管在编写的过程中出现了一些小问题(在打印代码时,打印命令的System.out.println的首字母忘记大写),但是最终我还是成功完成了这个程序的编写。

  • SAS 对数据集所有字段rename

     复制  复制 %macrornm(data=,out=); proccontentsdata=&data out=t1(keep=varnumname) noprint; run; procsqlnoprint; selectname into:classnameseparatedby'' fromt1 orderbyvarnum; quit; %put&classname; data&out; set&data; %leti=1; %do%until(%scan(&classname.,&i.,"")=); %letyn=%sysfunc(compress(%scan("&classname",&i,""))); rename&yn=C&i; %leti=%eval(&i.+1); %end; procdatasetsnolist; deletet1; run; %mend; /*调用*/ %rnm(data=test1,out=test2

  • 免费Git客户端:sourcetree详细介绍

    一、简介:一个用于Windows和Mac的免费Git客户端。Sourcetree简化了如何与Git存储库进行交互,这样您就可以集中精力编写代码。通过Sourcetree的简单GitGUI可视化和管理存储库。官网下载地址:Sourcetree|FreeGitGUIforMacandWindows 本文介绍的版本为sourcetree2.5.5;二、使用方法1、安装下载完成后,在安装SourceTree的过程中,需要通过账户登录,但注册或登录界面可能根本无法打开,导致软件无法正常安装。解决方法:(1)、在目录C:\Users\{youruser}\AppData\Local\Atlassian\SourceTree下创建文件accounts.json,注意:{youruser}需要替换为登录系统用户名。如我的电脑路径为:C:\Users\Administrator\AppData\Local\Atlassian\SourceTree。写入如下内容: [ { "$id":"1", "$type":"SourceTree.Api.Host.Identity.Model.Identi

  • linux高级考试错题集

    9.下面那句话是正确的 A.硬链接和软链接指向的inode的编号是一样的 B.不可以建立一个空文件的软链接 C.linux操作系统不可以对目录进行硬链接 D.硬链接指向inode节点 答案:A 10.执行以下程序:#!/bin/bashs=0for((i=1;i<=100;i++))doif["\(i"-eq50]thencontinuefis=\)((\(i+\)s))doneecho$s程序执行之后,输出的$s的结果是()? A.1225 B.2500 C.5000 D.5050 答案:D 11.在crontab定时任务中,设置“542,5*1命令”,请问该定时任务会在什么时间段执行() A.在每个月2号、5号凌晨4点整,和每周一的凌晨4点5分都执行此命令 B.在每个月的2号、5号,并且这一天还要是周一,才会在凌晨4点5分执行此命令 C.在每个月2号、5号凌晨4点整,和每周一的凌晨4点,每隔5分钟执行此命令1次 D.在每个月的2号、5号,并且这一天还要是周一,才会在凌晨4点,每隔5分钟执行此命令1次 答案:A 15.当路由器接收的IP报文中的目标网络不在路由表中时,将采取的策

相关推荐

推荐阅读