vue实现点击收藏按钮
Vue 实现点击收藏按钮
基本实现思路
使用 Vue 的数据绑定和事件处理功能,通过点击事件切换收藏状态。通常需要一个布尔值数据属性来跟踪收藏状态,并通过图标或文字的变化来反映状态。
<template>
<button @click="toggleFavorite">
{{ isFavorite ? '取消收藏' : '收藏' }}
</button>
</template>
<script>
export default {
data() {
return {
isFavorite: false
}
},
methods: {
toggleFavorite() {
this.isFavorite = !this.isFavorite
}
}
}
</script>
使用图标切换
结合 Font Awesome 或其他图标库,可以实现更直观的收藏按钮。这里以 Font Awesome 为例:
<template>
<button @click="toggleFavorite" class="favorite-button">
<i :class="['fas', isFavorite ? 'fa-heart' : 'fa-heart-o']"></i>
</button>
</template>
<script>
export default {
data() {
return {
isFavorite: false
}
},
methods: {
toggleFavorite() {
this.isFavorite = !this.isFavorite
}
}
}
</script>
<style>
.favorite-button {
background: none;
border: none;
cursor: pointer;
font-size: 24px;
color: #ff4757;
}
</style>
结合后端 API
实际应用中,收藏状态通常需要保存到后端。这里展示如何结合 axios 发送请求:
<template>
<button @click="toggleFavorite" :disabled="loading">
<i :class="['fas', isFavorite ? 'fa-heart' : 'fa-heart-o']"></i>
{{ loading ? '处理中...' : '' }}
</button>
</template>
<script>
import axios from 'axios'
export default {
props: {
itemId: {
type: Number,
required: true
}
},
data() {
return {
isFavorite: false,
loading: false
}
},
methods: {
async toggleFavorite() {
this.loading = true
try {
if (this.isFavorite) {
await axios.delete(`/api/favorites/${this.itemId}`)
} else {
await axios.post('/api/favorites', { item_id: this.itemId })
}
this.isFavorite = !this.isFavorite
} catch (error) {
console.error('操作失败:', error)
} finally {
this.loading = false
}
}
},
async created() {
try {
const response = await axios.get(`/api/favorites/check/${this.itemId}`)
this.isFavorite = response.data.isFavorite
} catch (error) {
console.error('获取收藏状态失败:', error)
}
}
}
</script>
使用 Vuex 管理状态
在大型应用中,可以使用 Vuex 来集中管理收藏状态:
// store/modules/favorites.js
export default {
state: {
favorites: []
},
mutations: {
ADD_FAVORITE(state, itemId) {
state.favorites.push(itemId)
},
REMOVE_FAVORITE(state, itemId) {
state.favorites = state.favorites.filter(id => id !== itemId)
}
},
actions: {
async toggleFavorite({ commit, state }, itemId) {
if (state.favorites.includes(itemId)) {
await axios.delete(`/api/favorites/${itemId}`)
commit('REMOVE_FAVORITE', itemId)
} else {
await axios.post('/api/favorites', { item_id: itemId })
commit('ADD_FAVORITE', itemId)
}
}
},
getters: {
isFavorite: state => itemId => state.favorites.includes(itemId)
}
}
组件中使用:
<template>
<button @click="toggleFavorite(itemId)" :disabled="loading">
<i :class="['fas', isFavorite(itemId) ? 'fa-heart' : 'fa-heart-o']"></i>
</button>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
export default {
props: {
itemId: {
type: Number,
required: true
}
},
computed: {
...mapGetters('favorites', ['isFavorite'])
},
methods: {
...mapActions('favorites', ['toggleFavorite'])
}
}
</script>
添加动画效果
为收藏按钮添加点击动画可以提升用户体验:
<template>
<button @click="toggleFavorite" class="favorite-button" :class="{ 'animate': isAnimating }">
<i :class="['fas', isFavorite ? 'fa-heart' : 'fa-heart-o']"></i>
</button>
</template>
<script>
export default {
data() {
return {
isFavorite: false,
isAnimating: false
}
},
methods: {
toggleFavorite() {
this.isAnimating = true
setTimeout(() => {
this.isFavorite = !this.isFavorite
this.isAnimating = false
}, 300)
}
}
}
</script>
<style>
.favorite-button {
background: none;
border: none;
cursor: pointer;
font-size: 24px;
color: #ff4757;
transition: transform 0.3s ease;
}
.favorite-button.animate {
transform: scale(1.2);
}
</style>
以上方法涵盖了从基础实现到进阶应用的多种场景,可以根据具体需求选择适合的方案。







