首先选一个主页面,进行简单的项目布局
<template>
<div class="FrameworkMainBody">
<nav class="nav">
<div class="nav-item ProhibitSelection"
v-for="component in Components"
:key="component.path"
@click="page = component.path">
{{ component.name }}
</div>
</nav>
<div class="component">
<Setting v-if="page === 'Setting'" />
<Lottery v-if="page === 'Lottery'" />
</div>
</div>
</template>
<script lang="ts" setup>
import Setting from './components/Setting.vue'
import Lottery from './components/Lottery.vue'
import {onMounted, ref} from "vue";
const Components = [
{ path: 'Lottery', name: '抽签' },
{ path: 'Setting', name: '设置' }
]
const page = ref('')
onMounted(()=>{
page.value = 'Lottery'
})
</script>
<style lang="less" scoped>
@import "./index.less";
</style>
紧接着奖抽签和设置被抽取的值,将此分为两个页面
抽签的
<template>
<div class="lottery">
<div class="current">{{ current }}</div>
<button class="button is-large is-warning" v-if="!timer" @click="start">开始</button>
<button class="button is-large is-danger" v-if="timer" @click="stop">停</button>
<table class="table" v-if="history.length > 0">
<thead>
<tr>
<th>轮次</th>
<th>中签号码</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in history" :key="index">
<td>{{ index + 1 }}</td>
<td>{{ item }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
const numbers = ref([])
const current = ref('')
const timer = ref(null)
const history = ref([])
const neverWin = computed(() => {
return numbers.value.filter((item) => !history.value.some((historyItem) => historyItem === item))
})
const random = (minNum, maxNum) => {
return Math.floor(Math.random() * (maxNum - minNum + 1) + minNum)
}
const start = () => {
if (neverWin.value.length < 1) {
alert('所有人都已中过签! 请到设置清空中签纪录!')
return
}
timer.value = setInterval(refresh, 10)
}
const stop = () => {
clearInterval(timer.value)
timer.value = null
saveHistory()
}
const refresh = () => {
current.value = neverWin.value[random(0, neverWin.value.length - 1)]
}
const saveHistory = () => {
history.value.push(current.value)
localStorage.setItem('history', JSON.stringify(history.value))
}
const readNumbers = () => {
const numStr = localStorage.getItem("numbers")
if (numStr) numbers.value = numStr.split('\n').filter((item) => !!item)
if (numbers.value.length === 0) {
alert('抽签池为空! 请到右上角设置中添加!')
numbers.value = ['11', '22', '33', '44', '55', '66', '77', '88', '99']
}
}
const readHistory = () => {
const historyData = localStorage.getItem("history")
if (historyData) history.value = JSON.parse(historyData)
}
onMounted(() => {
readNumbers()
readHistory()
current.value = numbers.value[0].split('').map(() => '*').join('')
})
</script>
<style lang="less" scoped>
@import "../index.less";
</style>
设置的
<template>
<div class="setting">
<h1>请设置抽签池</h1>
<h2>一行一个</h2>
<div class="field">
<div class="control">
<textarea class="textarea" v-model="numbers" />
</div>
</div>
<div class="field is-grouped">
<div class="control">
<button class="button is-primary" @click="save">保存</button>
</div>
<div class="control">
<button class="button" @click="clear">清空抽签历史</button>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import {onMounted, ref} from "vue";
const numbers: any= ref('')
function save () {
localStorage.setItem('numbers', numbers.value)
alert('已保存')
}
function clear () {
localStorage.setItem('history', '')
alert('已清空')
}
onMounted(()=> {
numbers.value = localStorage.getItem('numbers')
if (!numbers.value) {
numbers.value = ['11', '22', '33', '44', '55', '66', '77', '88', '99'].join('\n')
localStorage.setItem('numbers', numbers.value)
}
})
</script>
<style scoped>
@import "../index.less";
</style>
最后附加样式文件
body {
margin: 0;
}
.FrameworkMainBody{
height: 100%;
width: 100%;
background-image: url('@/assets/bg-2.jpg');
background-size: cover;
background-repeat: no-repeat;
position: relative;
}
.nav {
background-color: transparent;
position:absolute;
top: 0;
right: 10px;
display: flex;
}
.nav .nav-item {
cursor: pointer;
width: 4rem;
height: 3.25rem;
line-height: 3.25rem;
color: #ffffff;
text-align: center;
}
.nav .nav-item:hover {
background-color: rgba(255, 255, 255, 0.5);
}
.component {
position: absolute;
top: 3.25rem;
bottom: 0;
left: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
overflow: auto;
}
h1 {
font-size: 30px;
color: #ffffff;
}
h2 {
font-size: 20px;
color: #ffffff;
}
.current {
font-size: 12rem;
margin-bottom: 50px;
color: #ffffff;
}
.button.is-large {
width: 100px;
}
.table {
position: absolute;
left: 20px;
bottom: 20px;
background-color: transparent;
color: #ffffff;
}
.table thead td, .table thead th {
color: #ffffff;
}
.lottery{
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
h1 {
font-size: 30px;
margin-bottom: 6px;
}
h2 {
font-size: 20px;
margin-bottom: 10px;
}
.setting {
text-align: left;
width: 50%;
}
.textarea {
height: 300px;
}
::selection {
background-color: rgba(255, 255, 0, 0.5);
}
::-moz-selection {
background-color: rgba(255, 255, 0, 0.5);
}
至此,功能基本完善,可以根据自己的情况继续完善