vue3实现一个抽奖小项目
前言
- 在公司年会期间我做了个抽奖小项目,我把它分享出来,有用得着的可以看下。
- 浏览链接:http://xisite.top/original/luck-draw/index.html
- 项目链接:https://gitee.com/xi1213/luck-draw
- 项目截图:

实现目标
- 数据保存:无后端,纯前端实现,浏览器刷新或者关闭数据不能丢失。
- 姓名切换:点击中部开始按钮姓名快速切换。
- 奖项切换:奖项为操作人员手动切换设置。
- 历史记录:抽奖完成后需要有历史记录。
- 数据导入:允许参与人员的表格导入。
数据保存
无后台,纯前端实现而且需要刷新关闭浏览器数据不丢失,很容易便会想到使用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 = ""); //置空选中的文件
};
结语
- 项目很简单,但给我的时间很少,很多优化的地方都没做好,后面有时间了再优化下,顺便适配下移动端。
- 原文地址:https://xiblogs.top/?id=53
vue3实现一个抽奖小项目的更多相关文章
- Extjs6(一)——用sencha cmd建立一个ExtJs小项目
本文基于ext-6.0.0 一.用sencha cmd建立一个ExtJs小项目 首先,需要一个命令行工具.进入extjs所在目录. 然后,输入:sencha -sdk [ExtJs6.0文件夹地址] ...
- 创建第一个spirngmvc小项目
题外: 设置目录为源代码目录 1.进入:file->project structure->modules->soures 进入这个里面,选择相应的文件夹.例如src/java里的ja ...
- 实现android"转盘抽奖"小项目后感想
我这次做的小项目是android的转盘抽奖,因为这个小项目中有进程的调度,加锁等细节,而我们组的竞赛系统中也有这样的问题.通过这次的实践我发现了自己的好多问题也学到了很多. 个人问题: 1.自己的动手 ...
- 又见angular----步一步做一个angular4小项目
这两天看了看angular4的文档,发现他和angular1.X的差别真的是太大了,官方给出的那个管理英雄的Demo是一个非常好的入门项目,这里给出一个管理个人计划的小项目,从头至尾一步一步讲解如何去 ...
- 一个WPF小项目小结
一:缘起 老板有做PC桌面客户端的需求,做的是能耗的计算和评估,要算能耗,就有很多环节,最后对这些环节数据进行一些简单计算.我想要是做的话就用比较熟的wpf,就去聊了下,对方给了1张比较复杂的Exce ...
- scrapy的一个简单小项目
使用scrapy抓取目标url下所有的课程名和价格,并将数据保存为json格式url=http://www.tanzhouedu.com/mall/course/initAllCourse 观察网页并 ...
- express+mongoDB(mLab)做一个todolist小项目
这是在网课上学习的,先建立一个express-todolist文件夹作为项目跟目录 另外,我们直接把项目上用到的css文件和js文件下载下来放在项目里 这里直接贴出来 先建立一个public文件夹,放 ...
- 第一个Python小项目:图片转换成字符图片
实现的效果: ...
- 今天写了一个SSM小项目,运行之后,前端页面的CSS、js样式显示不出来,具体操作如下:
因为SSM中我们设置了拦截器,拦截器会拦截CSS和JS,所有样式渲染不出来,在Web.xml中写上 1 <servlet-mapping> 2 <servlet-name>de ...
- Web前端开发:SQL Jsp小项目(一)
Jsp的学习算是告一段落,针对这段时间的学习,写了一个Jsp小项目来巩固学到的知识. 框架示意图 User list process UserAdd process 需要的界面效果: 需要工具:Ecl ...
随机推荐
- 齐博x1频道的二次开发入门讲解
要进行频道的二次开发,首先我们要先了解一下频道的目录结构,如下图最基本的几个目录admin 后台文件存放目录index 前台文件存放目录member 会员中心存放目录model 数据表模型目录trai ...
- MIPI-DSI协议
MIPI联盟,即移动产业处理器接口(Mobile Industry Processor Interface 简称MIPI)联盟.MIPI(移动产业处理器接口)是MIPI联盟发起的为移动应用处理器制定的 ...
- 关于引用JS和CSS文件刷新浏览器缓存问题,部署服务器后客户端样式不刷新
问题描述 对样式的css文件进行了修改,部署到服务器后访问发现页面展示不正常,但是刷新之后就会展示正常. 问题分析 研究之后发现可能的原因有 css文件过大,加载缓慢 本地缓存问题,虽然服务器修改了c ...
- iptables规则查询
iptables规则查询 之前在iptables的概念中已经提到过,在实际操作iptables的过程中,是以"表"作为操作入口的,如果你经常操作关系型数据库,那么当你听到" ...
- BI系统打包Docker镜像及部署的技术难度和实现
BI系统打包Docker镜像及部署的技术难度和实现 随着容器化技术盛行,Docker在前端领域也有着越来越广泛的应用:传统的前端部署方式需要我们将项目打包生成一系列的静态文件,然后上传到服务器,配置n ...
- js把秒数转换为HH:MM:SS及时分秒格式
/** * 转为HH:MM:SS * @param second * @returns {string} * @private */ var _showTime = function (second) ...
- 第一章:TypeScript快速入门
一.TypeScript 开发环境搭建 1.TypeScript 是什么? TypeScript 是一种由微软开发的自由和开源的编程语言.它是 JavaScript 的一个超集,而且本质上向这个语言添 ...
- WIN10使用SSH连接VMWare16 Pro的CentOS8.4(保姆级)
目录 本机环境 配置连接 本机环境 连接工具用的是MobaXterm,下载地址https://mobaxterm.mobatek.net/download.html VMWare16 Pro Cent ...
- Centos7.6分区、格式化、自动挂载磁盘
个人名片: 对人间的热爱与歌颂,可抵岁月冗长 Github:念舒_C.ying CSDN主页️:念舒_C.ying 个人博客 :念舒_C.ying 目录 1. 添加硬盘 2. 执行fdisk -l ...
- Devexpress控件pivotGridControl显示字段面板
可在窗口加载的时候使用函数 pivotGridControl1.ShowCustomization(); 大家如果有问题可以 Console.WriteLine("加群"+&quo ...