首页 > 其他分享 >Vue.js 投票排行榜:从零到完整实现详细教程” “新手友好:使用 Vue.js 构建一个实时投票排行榜” “10分钟学会Vue.js:实现动态投票排行榜” “完整指南:用 Vue.js 开发带倒计

Vue.js 投票排行榜:从零到完整实现详细教程” “新手友好:使用 Vue.js 构建一个实时投票排行榜” “10分钟学会Vue.js:实现动态投票排行榜” “完整指南:用 Vue.js 开发带倒计

时间:2024-10-24 19:20:51浏览次数:12  
标签:ranking Vue color border js 60 排行榜 background margin

效果图

在这里插入图片描述

博客教程:使用Vue.js实现投票排行榜页面(详细步骤)

在本篇博客教程中,我们将逐步带你实现一个投票排行榜页面,使用的是Vue.js框架。此项目适合前端开发新手,可以帮助你更好地理解Vue的基本功能和组件开发。


目录
  1. 项目介绍
  2. 搭建项目基础结构
  3. 实现榜单前3名展示
  4. 实现倒计时功能
  5. 实现投票功能
  6. 剩余艺人展示与排序
  7. 底部导航与样式优化
  8. 总结与完整代码

项目介绍

我们将创建一个简单的投票排行榜页面。这个页面会展示艺人/团体的投票信息、投票截止时间、投票按钮等功能。我们还会增加倒计时功能,实时显示距离投票结束的时间。

你将学会如何:

  • 创建排行榜并根据票数排序
  • 实现简单的投票功能
  • 实现倒计时功能
  • 使用Vue.js的计算属性和生命周期方法

搭建项目基础结构

首先,我们需要定义HTML页面的基本结构和样式。创建一个基础的Vue.js应用,并编写简单的HTML和CSS来展示内容。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>投票排行榜 - Vue.js 实现</title>
    <script src="https://cdn.staticfile.net/vue/2.7.0/vue.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #fff;
            color: #333;
            text-align: center;
        }

        #app {
            max-width: 500px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f2f2f2;
        }

        .title {
            font-size: 24px;
            font-weight: bold;
            color: #fff;
            padding: 10px;
            background-color: #ff3b3b;
            margin-bottom: 20px;
        }

        .leaderboard {
            display: flex;
            justify-content: space-around;
            margin-bottom: 20px;
        }

        .leaderboard div {
            width: 80px;
            height: 80px;
            background-color: #ddd;
            border-radius: 50%;
            margin-bottom: 5px;
        }

        .leaderboard p {
            font-size: 16px;
            font-weight: bold;
            color: #ff3b3b;
        }

        .countdown {
            margin: 20px 0;
            font-size: 16px;
            color: #555;
        }

        .ranking-list {
            background-color: #fff;
            border-radius: 10px;
            padding: 10px;
            margin-bottom: 20px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        }

        .ranking-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
            padding: 10px 5px;
            border-bottom: 1px solid #eee;
        }

        .ranking-item:last-child {
            border-bottom: none;
        }

        .ranking-item div {
            display: flex;
            align-items: center;
        }

        .ranking-item div .avatar {
            width: 50px;
            height: 50px;
            background-color: #ddd;
            border-radius: 50%;
            margin-right: 10px;
        }

        .ranking-item div span {
            font-size: 18px;
            font-weight: bold;
            color: #333;
        }

        .ranking-item button {
            background-color: #ff3b3b;
            border: none;
            color: white;
            padding: 5px 10px;
            border-radius: 5px;
            cursor: pointer;
            transition: transform 0.2s ease;
        }

        .ranking-item button:hover {
            background-color: #d73232;
        }

        .ranking-item button:active {
            transform: scale(0.95);
        }

        .tabs {
            display: flex;
            justify-content: space-around;
            margin-top: 20px;
        }

        .tabs button {
            padding: 10px;
            border: none;
            background-color: #ff3b3b;
            color: white;
            border-radius: 5px;
            cursor: pointer;
        }

        .tabs button:hover {
            background-color: #d73232;
        }
    </style>
</head>
<body>
<div id="app">
    <div class="title">投票排行榜</div>

实现榜单前3名展示

我们需要显示榜单前三名的艺人,并为他们提供简单的样式(如圆形头像)。在Vue的数据模型中定义艺人及其票数,并通过计算属性来排序和展示前三名艺人。

    <div class="leaderboard">
        <div v-for="(artist, index) in topThree" :key="index">
            <p>{{ artist.name }}</p>
            <p>{{ artist.votes }}票</p>
        </div>
    </div>

实现倒计时功能

我们将使用mounted生命周期函数在组件加载时启动倒计时,并使用setInterval每秒更新倒计时数据。

    <div class="countdown">
        距离投票结束还有: {{ daysLeft }} 天 {{ hoursLeft }} 小时 {{ minutesLeft }} 分钟
    </div>

在Vue实例中,编写逻辑代码来计算并显示倒计时。

    mounted() {
        this.updateCountdown();
    },
    methods: {
        updateCountdown() {
            const endTime = new Date().getTime() + this.countdown;
            this.timer = setInterval(() => {
                const now = new Date().getTime();
                const distance = endTime - now;
                this.daysLeft = Math.floor(distance / (1000 * 60 * 60 * 24));
                this.hoursLeft = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
                this.minutesLeft = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
                if (distance < 0) {
                    clearInterval(this.timer);
                }
            }, 1000);
        }
    }

实现投票功能

在每个艺人的信息下方添加一个“投票”按钮,并在点击时增加对应艺人的票数。

    <div class="ranking-list">
        <div v-for="(artist, index) in remainingArtists" :key="index" class="ranking-item">
            <div>
                <div class="avatar"></div>
                <span>{{ artist.name }}</span>
            </div>
            <div>
                <span>{{ artist.votes }}票</span>
                <button @click="vote(index)">投票</button>
            </div>
        </div>
    </div>

剩余艺人展示与排序

我们将通过计算属性remainingArtists来筛选和展示剩余的艺人,并实现实时排序。

    computed: {
        topThree() {
            return this.artists.slice(0, 3);
        },
        remainingArtists() {
            return this.artists.slice(3);
        }
    },
    methods: {
        vote(index) {
            this.artists[index + 3].votes += 1;
        }
    }

底部导航与样式优化

添加底部导航按钮,并且实现简单的页面切换效果。

    <div class="tabs">
        <button>活动投票</button>
        <button>排名统计</button>
        <button>活动说明</button>
    </div>

总结与完整代码

通过这篇教程,我们学习了如何使用Vue.js实现一个投票排行榜页面。我们使用了Vue的计算属性、mounted生命周期方法以及setInterval函数实现了动态更新和实时投票的功能。

完整代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>投票排行榜 - Vue.js 实现</title>
    <script src="https://cdn.staticfile.net/vue/2.7.0/vue.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #fff;
            color: #333;
            text-align: center;
        }

        #app {
            max-width: 500px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f2f2f2;
        }

        .title {
            font-size: 24px;
            font-weight: bold;
            color: #fff;
            padding: 10px;
            background-color: #ff3b3b;
            margin-bottom: 20px;
        }

        .leaderboard {
            display: flex;
            justify-content: space-around;
            margin-bottom: 20px;
        }

        .leaderboard div {
            width: 80px;
            height: 80px;
            background-color: #ddd;
            border-radius: 50%;
            margin-bottom: 5px;
        }

        .leaderboard p {
            font-size: 16px;
            font-weight: bold;
            color: #ff3b3b;
        }

        .countdown {
            margin: 20px 0;
            font-size: 16px;
            color: #555;
        }

        .ranking-list {
            background-color: #fff;
            border-radius: 10px;
            padding: 10px;
            margin-bottom: 20px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        }

        .ranking-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
            padding: 10px 5px;
            border-bottom: 1px solid #eee;
        }

        .ranking-item:last-child {
            border-bottom: none;
        }

        .ranking-item div {
            display: flex;
            align-items: center;
        }

        .ranking-item div .avatar {
            width: 50px;
            height: 50px;
            background-color: #ddd;
            border-radius: 50%;
            margin-right: 10px;
        }

        .ranking-item div span {
            font-size: 18px;
            font-weight: bold;
            color: #333;
        }

        .ranking-item button {
            background-color: #ff3b3b;
            border: none;
            color: white;
            padding: 5px 10px;
            border-radius: 5px;
            cursor: pointer;
            transition: transform 0.2s ease;
        }

        .ranking-item button:hover {
            background-color: #d73232;
        }

        .ranking-item button:active {
            transform: scale(0.95);
        }

        .tabs {
            display: flex;
            justify-content: space-around;
            margin-top: 20px;
        }

        .tabs button {
            padding: 10px;
            border: none;
            background-color: #ff3b3b;
            color: white;
            border-radius: 5px;
            cursor: pointer;
        }

        .tabs button:hover {
            background-color: #d73232;
        }
    </style>
</head>
<body>
<div id="app">
    <div class="title">投票排行榜</div>

    <!-- 榜单前三展示 -->
    <div class="leaderboard">
        <div v-for="(artist, index) in topThree" :key="index">
            <p>{{ artist.name }}</p>
            <p>{{ artist.votes }}票</p>
        </div>
    </div>

    <!-- 倒计时 -->
    <div class="countdown">
        距离投票结束还有: {{ daysLeft }} 天 {{ hoursLeft }} 小时 {{ minutesLeft }} 分钟
    </div>

    <!-- 排名列表 -->
    <div class="ranking-list">
        <div v-for="(artist, index) in remainingArtists" :key="index" class="ranking-item">
            <div>
                <div class="avatar"></div>
                <span>{{ artist.name }}</span>
            </div>
            <div>
                <span>{{ artist.votes }}票</span>
                <button @click="vote(index)">投票</button>
            </div>
        </div>
    </div>

    <!-- 底部导航 -->
    <div class="tabs">
        <button>活动投票</button>
        <button>排名统计</button>
        <button>活动说明</button>
    </div>
</div>

<script>
new Vue({
    el: '#app',
    data: {
        countdown: 5 * 24 * 60 * 60 * 1000, // 5天的倒计时
        artists: [
            { name: '黄飞燕', votes: 9690 },
            { name: '张彬彬', votes: 8690 },
            { name: '刘丹妮', votes: 8655 },
            { name: 'A12号 西建科', votes: 12350 },
            { name: 'A09号 孙萌萌', votes: 12089 },
            { name: 'A09号 司马学', votes: 12001 },
            { name: 'A06号 王珊珊', votes: 11984 },
            { name: 'A02号 何华康', votes: 11980 },
            { name: 'A08号 赵小菜', votes: 11978 }
        ],
        timer: null,
        daysLeft: 0,
        hoursLeft: 0,
        minutesLeft: 0
    },
    computed: {
        topThree() {
            return this.artists.slice(0, 3);
        },
        remainingArtists() {
            return this.artists.slice(3);
        }
    },
    methods: {
        vote(index) {
            this.artists[index + 3].votes += 1;
        },
        updateCountdown() {
            const endTime = new Date().getTime() + this.countdown;
            this.timer = setInterval(() => {
                const now = new Date().getTime();
                const distance = endTime - now;
                this.daysLeft = Math.floor(distance / (1000 * 60 * 60 * 24));
                this.hoursLeft = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
                this.minutesLeft = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
                if (distance < 0) {
                    clearInterval(this.timer);
                }
            }, 1000);
        }
    },
    mounted() {
        this.updateCountdown();
    }
});
</script>
</body>
</html>


标签:ranking,Vue,color,border,js,60,排行榜,background,margin
From: https://blog.csdn.net/qq_22182989/article/details/143175740

相关文章

  • Nodejs版本管理及镜像配置
    pnpm安装Windows(PowerShell)Invoke-WebRequesthttps://get.pnpm.io/install.ps1-UseBasicParsing|Invoke-Expressionhttps://pnpm.io/zh/installationPOSIX系统curl-fsSLhttps://get.pnpm.io/install.sh|sh-更新pnpmself-update配置node镜像pnpmconfi......
  • Vue中使用el-upload实现文件上传时控制提交按钮状态的最佳实践
    在Web应用开发中,文件上传是一个常见的需求。在使用Vue框架和ElementUI库时,我们经常使用el-upload组件来处理文件上传。但是,如何在上传过程中控制提交按钮的可用状态,以避免在上传未完成时误触提交操作,是一个值得探讨的问题。本文将介绍一种简单有效的方法来解决这个问题。问......
  • 基于vben框架的vue前端代码编译时报错
    在Node18.16和16.20版本下使用vben框架时,遇到pnpminstall报错关于eslint-config缺失的问题,解决方案是通过添加pnpm-workspace.yaml文件并指定内部依赖,确保`@vben/eslint-config`版本配置正确。问题描述node18.16/node16.20中编译vben框架的vue前端代码,pnpminstall报错:"@v......
  • 计算机毕业设计项目推荐:大学生实习成绩评价系统的设计与实现38147(开题答辩+程序定制+
    摘 要21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存储达到准确、快速、完善,并能提高工作管理效率,促进其发展。论文主要是对大学生实习成绩......
  • 计算机毕业设计项目推荐,个人知识管理系统 79004(开题答辩+程序定制+全套文案 )上万套实
    摘 要尽管我们每天面临的信息越来越多,信息过载与信息噪音越来越严重,但只要我们能充分利用个人知识管理技能,借助有效的个人知识管理软件相信战胜海量信息不再是困难。本课题在分析了个人知识管理现状以及对现有的个人知识管理网站进行研究比较的基础上,针对网络交流互助的特......
  • 2024-10-24 瀑布流(vue3)
    效果图: 代码: <template><divid="waterfallContainer"class="waterfall-container"><divv-for="(column,columnIndex)incolumns":key="columnIndex"class="waterfall-column">......
  • vue3入门教程,一站学会全套vue!
    vue3vue3作为前端重要的框架,学会vue可以让你更加了解前端。本博客致力于让你一站学会vue3的全部内容,从小白到高手。全是干货,准备好了吗?文章目录vue3创建工程文档结构核心语法模板语法插值语法指令语法无参指令有参指令自定义指令setupsetup函数setup语法糖响应式数......
  • 安装node及vue项目的启动
    1、ubuntu安装npmsudoaptinstallnodejsnpm2、设置包下载源npmconfigsetregistryhttps://registry.npmmirror.com/3.安装包及运行npminstall安装成功后会生成一个node_moudels目录运行:npmrunserve4、常见报错及解决方式(1)oldlockfile报错npmWARNoldlo......
  • js五子棋效果
    任务分解一、绘制棋盘二、绑定事件1、先计算出需要绘制棋子的坐标即将来绘制的棋子在哪个单元格内2、绘制棋子首先判断棋子是否存在应该添加到哪个单元格内,分四种情况:1.1正常情况  1.2最右侧超出边界只能放在最后一个单元格内 1.3 左下侧超出边界只能放在最......
  • vue3 学习笔记(不断更新中...)
    组合式APIsetup()11响应式APIrefref用于创建响应式数据(通常用来定义基本类型数据)在JavaScript代码中,需要使用.value来操作数据letcount=ref(1)console.log(count.value)//1count.value++console.log(count.value)//2在Template模板中不需要<scriptse......