用vue3写一个抽签的功能模块

首先选一个主页面,进行简单的项目布局

<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);
}

至此,功能基本完善,可以根据自己的情况继续完善

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值