如果使用v-for的方式来循环遍历生成li,那么你在li上面注册的事件都会是同一个事件,这显然不是我们想要的。这样会造成一个问题,就是当我们点击一个li的时候,因为所有的Li绑定的都是同一个事件,所以这里事件的回调函数都会触发,但是我们又不可能给每一个li都绑定一个不同的事件,因为我们不知道有多少个li,而且这样代码会比较冗杂。
所以,理想的状态是,就注册一个事件,所有li公用一个事件处理函数,然后我们把事件中所有的数据绑定都绑定到item,就是当前遍历的那一个对象上,把这个对象传给事件处理函数,根据item来区分不同的Li。
现在有一个需求,需要使用列表循环来渲染视图,列表的每一项都有点赞和收藏的功能,当点击收藏,图标变红,表示已收藏,当点击赞的时候,图标变红,点赞数+1,当然每个li需要有自己的点赞数,不能相互影响。
template
<ul>
<li class="topicalList-item" v-for="(item, idx) in list" :key="idx">
<van-row>
<van-col>
<img v-if="!item.avatar.length" class="topicalList-item-avatar" src="../../assets/img/default-avatar.png" alt="">
<img v-if="item.avatar.length" class="topicalList-item-avatar" :src="item.avatar" alt="">
</van-col>
<van-col>
<span>{{ item.name.length? item.name: '匿名'}}</span>
<i class="topicalList-item-tag" v-if="item.tag.length">
{{ item.tag.length? item.tag: '' }}
</i>
<p>{{ item.time }}</p>
</van-col>
</van-row>
<h4>{{ item.title }}</h4>
<h5>{{ item.content }}</h5>
<van-row class="topicalList-item-bottom">
<!-- 收藏=============================== -->
<van-col span="8">
<img
src="../../assets/img/start-k.png"
v-if="!item.collection"
:class="{'clickAnimate': item.animateStyle === 'start'}"
@click="clickStart(item)">
<img
src="../../assets/img/start.png"
v-if="item.collection"
:class="{'clickAnimate': item.animateStyle === 'start-cancel'}"
@click="cancelStart(item)">
<i>收藏</i>
</van-col>
<van-col span="8" class="topicalList-item-chart">
<img src="../../assets/img/chart.png" alt="">
<i>{{ item.chartNum }}</i>
</van-col>
<!-- 点赞=============================== -->
<van-col span="8" class="topicalList-item-zan">
<img
v-if="!item.zan"
src="../../assets/img/good-k.png"
:class="{'clickAnimate': item.animateStyle === 'good'}"
@click="clickZan(item)">
<img
v-if="item.zan"
src="../../assets/img/good.png"
:class="{'clickAnimate': item.animateStyle === 'good-cancel'}"
@click="cancelZan(item)">
<i>{{ item.zanNum }}</i>
</van-col>
</van-row>
</li>
</ul>
js
<script>
let list = [
{
id: 1,
name: '',
tag: '',
avatar: '',
time: '2019-08-07 09:29:58',
title: '第三个测试',
content: '这是一个测试内容',
chartNum: '120',
zanNum: '201',
zan: false,
collection: false,
animateStyle: '',
},
]
export default {
data: function () {
return {
value: '',
activeName: '',
activeStyle: 'all',
topicShow: 'allTopic',
list,
}
},
methods: {
// 点击收藏
clickStart: function (item) {
item.animateStyle = 'start'// 控制动画
setTimeout(() => {
item.collection = !item.collection // 控制显示空心还是红心
}, 600)
},
// 取消收藏
cancelStart: function (item) {
item.animateStyle = 'start-cancel'
setTimeout(() => {
item.collection = !item.collection
}, 600)
},
// 点赞
clickZan: function (item) {
item.animateStyle = 'good'
item.zanNum++ // 每个li都有自己的点赞数
setTimeout(() => { // 这里的括号不能传item,否则就是undefined
item.zan = !item.zan
}, 600)
},
// 取消赞
cancelZan: function (item) {
item.animateStyle = 'good-cancel'
item.zanNum--
setTimeout(() => {
item.zan = !item.zan
}, 600)
}
},
}
</script>
当然这只是我能够想到的一种方式,大家可以参考一下。如果有更好的实现方式,小伙伴们可以在下方留言。样式部分写的比较乱,就不放上去了。