0
点赞
收藏
分享

微信扫一扫

使用Vue.js构建年会抽奖应用:动态调整抽奖概率的实践与代码示例

引言

年会是企业文化的缩影,而抽奖环节往往能极大地提升员工的参与度和幸福感。本文将介绍如何使用Vue.js框架构建一个年会抽奖应用,该应用不仅具备基本的抽奖功能,还能允许管理员动态调整各个奖项的中奖概率,从而增加抽奖的趣味性和公平性。

技术栈
  • 前端框架:Vue.js 3
  • 状态管理:Vuex 4(用于全局状态管理)
  • UI组件库:Element Plus(用于快速构建用户界面)
  • 路由管理:Vue Router 4(虽然本示例较为简单,但展示了基本的路由配置)
项目结构

/src
  /assets         # 静态资源文件夹
  /components     # Vue组件文件夹
    - Draw.vue    # 抽奖界面组件
    - Admin.vue   # 管理员界面组件
  /store          # Vuex状态管理文件夹
    - index.js    # Vuex主文件
  /views          # 页面视图文件夹
    - Home.vue    # 主页视图
    - AdminPage.vue # 管理员页面视图
  App.vue         # 根组件
  main.js         # 入口文件
router/index.js   # Vue Router配置

实现步骤
  1. 初始化项目:使用Vue CLI创建一个新的Vue 3项目,并安装Element Plus和Vuex。

vue create annual-meeting-lottery
cd annual-meeting-lottery
vue add router
vue add vuex
npm install element-plus --save

  1. 配置Vuex:在/store/index.js中定义状态管理逻辑,包括奖项列表和概率配置。

// /store/index.js
import { createStore } from 'vuex';

export default createStore({
  state: {
    prizes: [
      { name: '一等奖', probability: 0.01 },
      { name: '二等奖', probability: 0.05 },
      { name: '三等奖', probability: 0.1 },
      // 更多奖项...
      { name: '参与奖', probability: 0.84 }
    ],
    selectedPrize: null
  },
  mutations: {
    setPrizes(state, prizes) {
      state.prizes = prizes;
    },
    setSelectedPrize(state, prize) {
      state.selectedPrize = prize;
    }
  },
  actions: {
    draw({ commit, state }) {
      const totalProbability = state.prizes.reduce((sum, prize) => sum + prize.probability, 0);
      const random = Math.random();
      let cumulativeProbability = 0;
      for (let prize of state.prizes) {
        cumulativeProbability += prize.probability / totalProbability;
        if (random < cumulativeProbability) {
          commit('setSelectedPrize', prize);
          break;
        }
      }
    }
  },
  getters: {
    prizes: state => state.prizes,
    selectedPrize: state => state.selectedPrize
  }
});

  1. 创建抽奖组件:在/components/Draw.vue中实现抽奖界面和按钮点击事件。

<!-- /components/Draw.vue -->
<template>
  <div class="draw-container">
    <el-button type="primary" @click="startDrawing">开始抽奖</el-button>
    <div v-if="selectedPrize">
      <h2>恭喜你抽中:{{ selectedPrize.name }}</h2>
    </div>
  </div>
</template>

<script>
import { mapActions, mapGetters } from 'vuex';

export default {
  computed: {
    ...mapGetters(['selectedPrize'])
  },
  methods: {
    ...mapActions(['draw']),
    startDrawing() {
      this.draw();
      // 可添加动画效果,例如使用CSS动画或第三方动画库
      setTimeout(() => {
        this.$message.success(`恭喜你抽中:${this.selectedPrize.name}`);
      }, 1000); // 模拟动画延迟
    }
  },
  data() {
    return {
      selectedPrize: null
    };
  },
  watch: {
    selectedPrize(newVal) {
      if (newVal) {
        // 可以在这里重置抽奖状态或执行其他逻辑
      }
    }
  }
};
</script>

<style scoped>
.draw-container {
  text-align: center;
  margin-top: 50px;
}
</style>

  1. 创建管理员界面:在/components/Admin.vue中实现奖项和概率的编辑功能。

<!-- /components/Admin.vue -->
<template>
  <div class="admin-container">
    <el-form :model="form">
      <el-form-item v-for="(prize, index) in prizes" :key="index" :label="'奖项 ' + (index + 1)">
        <el-input v-model="prize.name" placeholder="请输入奖项名称"></el-input>
        <el-input-number v-model="prize.probability" :controls="false" placeholder="请输入中奖概率"></el-input-number>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="savePrizes">保存</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex';

export default {
  data() {
    return {
      form: {}
    };
  },
  computed: {
    ...mapState(['prizes'])
  },
  methods: {
    ...mapMutations(['setPrizes']),
    savePrizes() {
      // 这里假设直接保存当前state中的prizes,实际应用中可能需要发送到后端保存
      this.setPrizes([...this.prizes]);
      this.$message.success('奖项配置已保存');
    }
  }
};
</script>

<style scoped>
.admin-container {
  width: 60%;
  margin: 0 auto;
}
</style>

  1. 配置路由:在/router/index.js中配置抽奖页面和管理员页面的路由。

// /router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import AdminPage from '../views/AdminPage.vue';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/admin',
    name: 'Admin',
    component: AdminPage
  }
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
});

export default router;

  1. 创建视图组件:在/views文件夹下创建Home.vueAdminPage.vue,分别用于展示抽奖界面和管理员界面。

<!-- /views/Home.vue -->
<template>
  <div>
    <Draw />
    <el-button type="text" @click="goToAdmin">管理员配置</el-button>
  </div>
</template>

<script>
import Draw from '../components/Draw.vue';

export default {
  components: { Draw },
  methods: {
    goToAdmin() {
      this.$router.push('/admin');
    }
  }
};
</script>

<!-- /views/AdminPage.vue -->
<template>
  <div>
    <Admin />
    <el-button type="text" @click="goToHome">返回抽奖页面</el-button>
  </div>
</template>

<script>
import Admin from '../components/Admin.vue';

export default {
  components: { Admin },
  methods: {
    goToHome() {
      this.$router.push('/');
    }
  }
};
</script>

  1. 集成Element Plus:在/main.js中引入Element Plus组件库。

// /main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index

举报

相关推荐

0 条评论