当前位置:首页 > 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
分享给朋友:

相关文章

vue实现签约合作弹窗

vue实现签约合作弹窗

实现签约合作弹窗的步骤 使用Vue实现签约合作弹窗可以通过组件化方式完成,结合模态框和表单交互逻辑。以下是具体实现方法: 1. 创建弹窗组件 新建一个Vue组件文件(如SignContractDi…

vue实现视窗

vue实现视窗

Vue 实现视窗功能 在 Vue 中实现视窗功能通常涉及监听浏览器窗口大小变化、响应式布局或创建自定义弹窗组件。以下是几种常见实现方式: 监听浏览器窗口大小变化 使用 Vue 的 mounted 和…

vue实现摘要

vue实现摘要

Vue 实现摘要的方法 在 Vue 中实现文本摘要功能通常涉及截取文本的前部分内容并添加省略号。可以通过计算属性、过滤器或自定义指令来实现。 计算属性实现 在 Vue 组件中定义一个计算属性,用于…

vue 方法实现

vue 方法实现

在 Vue 中,方法的实现通常通过 methods 选项完成。以下是 Vue 方法实现的核心要点和示例: 基本方法定义 在 Vue 组件中定义方法时,需将函数声明放在 methods 对象内。这些…

vue实现拍照

vue实现拍照

Vue实现拍照功能 在Vue中实现拍照功能通常需要结合浏览器的MediaDevices API和Canvas元素。以下是具体实现方法: 安装依赖(可选) 如果需要更简单的封装,可以安装vue-web…

vue实现 toast

vue实现 toast

Vue 实现 Toast 组件 在 Vue 中实现 Toast 组件可以通过多种方式完成,以下是几种常见的方法: 使用全局组件和事件总线 创建一个全局的 Toast 组件,并通过事件总线或 Vue…