Vue 在 v-for 中通过 v-bind 绑定 class 在某些情况下无效的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cstome
V2EX    问与答

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

  •  
  •   cstome 2017-06-07 22:14:49 +08:00 8362 次点击
    这是一个创建于 3053 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概 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 的绑定就无效了。

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

    https://cn.vuejs.org/v2/guide/list.html#注意事项
    cstome
        4
    cstome  
    OP
       2017-06-09 16:41:41 +08:00
    @ck65 我仔细排查了一下,发现是这种情况就会: https://jsfiddle.net/589g0koo/6/
    这是为什么?
    cstome
        5
    cstome  
    OP
       2017-06-09 16:44:48 +08:00
    @ck65 上面链接不对,是 https://jsfiddle.net/589g0koo/7/
    mogita
        6
    mogita  
       2017-06-09 17:42:54 +08:00
    用 Vue.set() 方法,文档参考 #3 楼
    https://jsfiddle.net/589g0koo/8/
    cstome
        7
    cstome  
    OP
       2017-06-09 18:09:03 +08:00
    @ck65 我是在想将 arr 赋值给 list 跟 realList 是无关的,为什么会影响到?
    mogita
        8
    mogita  
       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
        9
    cstome  
    OP
       2017-06-10 02:03:12 +08:00
    @ck65 还是这个 jsfiddle.net/589g0koo/7/
    你把 19 行的赋值给删了,问题就不存在了。
    ```
    请不要在每一个回复中都包括外链,这看起来像是在 spamming
    ```
    V2EX 竟然说我是 spamming
    mogita
        10
    mogita  
       2017-06-10 12:06:06 +08:00
    哦,一定要存在这个 19 行的操作的话,改成这样即可 this.list = arr.map(item => Object.assign({}, item))

    你需要了解一下几个 JS 的关键特性(或许你已经了解,只当我提一下):变量赋值时的值传递和值引用的区别,Object 型引用赋值的坑,数组的深复制和浅复制。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5519 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 07:26 PVG 15:26 LAX 00:26 JFK 03:26
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86