当前位置:首页 > VUE

vue实现点赞

2026-02-17 16:12:02VUE

Vue 实现点赞功能

在 Vue 中实现点赞功能可以通过数据绑定和事件处理来完成。以下是几种常见的实现方式:

vue实现点赞

基础实现

<template>
  <button @click="toggleLike">
    {{ isLiked ? '取消点赞' : '点赞' }} ({{ likeCount }})
  </button>
</template>

<script>
export default {
  data() {
    return {
      isLiked: false,
      likeCount: 0
    }
  },
  methods: {
    toggleLike() {
      this.isLiked = !this.isLiked
      this.likeCount += this.isLiked ? 1 : -1
    }
  }
}
</script>

带动画效果实现

<template>
  <button @click="toggleLike" class="like-button">
    <transition name="bounce">
      <span v-if="isLiked" key="liked">❤️</span>
      <span v-else key="unliked">🤍</span>
    </transition>
    {{ likeCount }}
  </button>
</template>

<script>
export default {
  data() {
    return {
      isLiked: false,
      likeCount: 0
    }
  },
  methods: {
    toggleLike() {
      this.isLiked = !this.isLiked
      this.likeCount += this.isLiked ? 1 : -1
    }
  }
}
</script>

<style>
.bounce-enter-active {
  animation: bounce-in 0.5s;
}
.bounce-leave-active {
  animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}
</style>

与后端交互实现

<template>
  <button @click="toggleLike" :disabled="loading">
    {{ isLiked ? '取消点赞' : '点赞' }} ({{ likeCount }})
  </button>
</template>

<script>
import axios from 'axios'

export default {
  props: {
    postId: {
      type: Number,
      required: true
    }
  },
  data() {
    return {
      isLiked: false,
      likeCount: 0,
      loading: false
    }
  },
  created() {
    this.fetchLikeStatus()
  },
  methods: {
    async fetchLikeStatus() {
      try {
        const response = await axios.get(`/api/posts/${this.postId}/likes`)
        this.isLiked = response.data.isLiked
        this.likeCount = response.data.likeCount
      } catch (error) {
        console.error('获取点赞状态失败:', error)
      }
    },
    async toggleLike() {
      this.loading = true
      try {
        if (this.isLiked) {
          await axios.delete(`/api/posts/${this.postId}/likes`)
          this.likeCount--
        } else {
          await axios.post(`/api/posts/${this.postId}/likes`)
          this.likeCount++
        }
        this.isLiked = !this.isLiked
      } catch (error) {
        console.error('操作点赞失败:', error)
      } finally {
        this.loading = false
      }
    }
  }
}
</script>

使用 Vuex 管理状态

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    likes: {}
  },
  mutations: {
    SET_LIKE_STATUS(state, { postId, isLiked, likeCount }) {
      Vue.set(state.likes, postId, { isLiked, likeCount })
    }
  },
  actions: {
    async toggleLike({ commit, state }, postId) {
      const current = state.likes[postId] || { isLiked: false, likeCount: 0 }
      const newStatus = !current.isLiked

      try {
        const response = await axios({
          method: newStatus ? 'post' : 'delete',
          url: `/api/posts/${postId}/likes`
        })

        commit('SET_LIKE_STATUS', {
          postId,
          isLiked: newStatus,
          likeCount: response.data.likeCount
        })
      } catch (error) {
        console.error('操作点赞失败:', error)
      }
    }
  }
})
<!-- LikeButton.vue -->
<template>
  <button @click="toggleLike" :disabled="loading">
    {{ isLiked ? '取消点赞' : '点赞' }} ({{ likeCount }})
  </button>
</template>

<script>
import { mapState } from 'vuex'

export default {
  props: {
    postId: {
      type: Number,
      required: true
    }
  },
  computed: {
    ...mapState({
      likes: state => state.likes
    }),
    isLiked() {
      return this.likes[this.postId]?.isLiked || false
    },
    likeCount() {
      return this.likes[this.postId]?.likeCount || 0
    }
  },
  data() {
    return {
      loading: false
    }
  },
  methods: {
    toggleLike() {
      this.loading = true
      this.$store.dispatch('toggleLike', this.postId)
        .finally(() => {
          this.loading = false
        })
    }
  }
}
</script>

以上实现方式可以根据项目需求选择适合的方案,从简单的前端交互到完整的后端集成都有涵盖。

标签: vue
分享给朋友:

相关文章

vue实现alert

vue实现alert

实现自定义 Alert 组件 在 Vue 中可以通过组件化方式实现自定义 Alert 弹窗。以下是基于 Vue 3 的实现示例: 组件代码 (Alert.vue) <template>…

分页实现vue

分页实现vue

分页实现(Vue) 在Vue中实现分页功能通常需要结合前端分页逻辑和后端API支持。以下是两种常见的实现方式: 前端分页实现 适用于数据量较小的情况,直接在客户端完成分页逻辑。 <templ…

jquery实现vue

jquery实现vue

jQuery 和 Vue.js 是两种不同理念的前端工具,jQuery 以 DOM 操作和事件驱动为核心,而 Vue.js 是数据驱动的现代化框架。如果想用 jQuery 实现类似 Vue 的功能(如…

vue实现xterm

vue实现xterm

在 Vue 中集成 Xterm.js Xterm.js 是一个基于 TypeScript 的前端终端组件库,可用于在浏览器中实现终端功能。以下是在 Vue 项目中集成 Xterm.js 的详细步骤。…

vue jwt实现

vue jwt实现

Vue JWT 实现方法 安装依赖 确保项目中安装了 jsonwebtoken(后端)和 axios(前端)。若使用 Vue 3,可搭配 vue-router 和 pinia(或 vuex)管理状态。…

vue实现表单

vue实现表单

Vue 表单实现方法 双向数据绑定 使用 v-model 指令实现表单元素与数据的双向绑定。适用于 input、textarea、select 等元素。 <template> <…