Vue 在 v-for 中通过 v-bind 绑定 class 在某些情况下无效的问题

2017-06-07 22:14:49 +08:00
 cstome

大概 HTML:

<div id="productSelect">
	<li v-bind:class="{'active' : item.selected}" v-for="(item, index) in list" @click="selectItem(index)">{{item.name}}</li>
</div>

JS:

var productChoice = new Vue({
	el: "#productSelect",
	data: {
		list: []
	},
	created: function() {
		this.loadDate();
	},
	methods: {
		loadDate: function () {
			//AJAX, 成功后传一个 Array 给 printProductList
			this.printProductList(arr);
		},
		selectItem: function(i) {
			this.list[i].selected = !(this.list[i].selected);
		},
		printProductList: function(arr) {
			let list = [];
			for(x in arr) {
				//经过某从筛选,通过的 push 到 list
				arr[x].selected = false; //每个条目中原先是没有 selected 这个属性的,这里加上去
				list.push(arr[x]);
			}
			this.list = list;
		}
	})
        

神奇的地方在于,如果直接写死 data.list 就能实现 class 的绑定,但是经过一系列处理之后赋值过去的 Array,虽然渲染得出来,但是通过点击来处理 class 的绑定就无效了。

8064 次点击
所在节点    问与答
10 条回复
ck65
2017-06-07 22:35:42 +08:00
似乎没有发现描述中的情况,这种复现的对不? https://jsfiddle.net/589g0koo/5/
SourceMan
2017-06-07 22:43:31 +08:00
v-for in template block
coo
2017-06-08 09:18:22 +08:00
你要使用 this.$set 来解决这个问题,直接更改变量是无法监听改变的。

https://cn.vuejs.org/v2/guide/list.html#注意事项
cstome
2017-06-09 16:41:41 +08:00
@ck65 我仔细排查了一下,发现是这种情况就会: https://jsfiddle.net/589g0koo/6/
这是为什么?
cstome
2017-06-09 16:44:48 +08:00
@ck65 上面链接不对,是 https://jsfiddle.net/589g0koo/7/
ck65
2017-06-09 17:42:54 +08:00
用 Vue.set() 方法,文档参考 #3 楼
https://jsfiddle.net/589g0koo/8/
cstome
2017-06-09 18:09:03 +08:00
@ck65 我是在想将 arr 赋值给 list 跟 realList 是无关的,为什么会影响到?
ck65
2017-06-09 18:59:51 +08:00
「为什么会影响到」=> 什么影响到了什么?不太明白你的问题。
19 行对 this.list 赋值之后没有任何地方使用 this.list,所以一直都在操作 this.realList,这两个 $data 属性扯不上关系。。

问题的核心在于 arr 的元素属性是 Object,对它们直接追加 /删除属性是无法被 Vue 直接检测的,需要使用 Vue.set()、Vue.delete() 方法( 2.x )。参考 https://vuejs.org/v2/api/#Vue-set
cstome
2017-06-10 02:03:12 +08:00
@ck65 还是这个 jsfiddle.net/589g0koo/7/
你把 19 行的赋值给删了,问题就不存在了。
```
请不要在每一个回复中都包括外链,这看起来像是在 spamming
```
V2EX 竟然说我是 spamming
ck65
2017-06-10 12:06:06 +08:00
哦,一定要存在这个 19 行的操作的话,改成这样即可 this.list = arr.map(item => Object.assign({}, item))

你需要了解一下几个 JS 的关键特性(或许你已经了解,只当我提一下):变量赋值时的值传递和值引用的区别,Object 型引用赋值的坑,数组的深复制和浅复制。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/366774

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX