Vue中动态修改b-icon的variant属性点击投票后未生效问题
问题原因及解决方案
核心原因
- Vue 2的响应式系统基于
Object.defineProperty实现,无法监听对象新增属性、数组通过索引直接赋值的操作,你遇到的是典型的响应式丢失问题,符合两种场景之一:- 初始化
votingList时,没有提前声明对应news._id的键,后续动态添加的键无法被Vue监听 votingList[news._id]对应的对象初始化时,没有提前声明upvoted/downvoted属性,后续直接赋值属于新增属性,不会触发视图更新
- 初始化
- 你手动调用
this.upvoteVariant(news)没有任何作用,该方法只是返回计算结果,并没有触发视图重新渲染的能力,只有当绑定的响应式数据变更时,模板里的绑定方法才会自动重新执行。
解决方案
替换你代码中直接赋值的语句,用Vue提供的$setAPI来修改属性,确保修改操作能被Vue监听到:
把upvote方法里的
this.votingList[news._id].upvoted = true
替换为:
// 先判断目标对象是否存在,不存在则初始化 if (!this.votingList[news._id]) { this.$set(this.votingList, news._id, { upvoted: true, downvoted: false }) } else { // 修改已有对象的属性,同时自动取消向下投票状态(按业务需要可选) this.$set(this.votingList[news._id], 'upvoted', true) this.$set(this.votingList[news._id], 'downvoted', false) }
如果你的项目是Vue 3,则不需要用$set,只需要确保votingList是用reactive或者ref定义的响应式数据即可。
补充说明
你在控制台能看到votingList的值已经更新,是因为控制台打印的是对象的引用,后续属性变更会同步展示在控制台中,但这并不代表Vue监听到了该次变更。
内容的提问来源于stack exchange,提问作者CorvusRex
相关产品推荐
相关产品推荐

