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

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

时间:2024-10-24 19:20:51浏览次数:19  
标签: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

相关文章