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







