V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
aoscici2000
V2EX  ›  Vue.js

v-for 使用请求的数据 :class 判断不生效

  •  
  •   aoscici2000 · 2019-08-04 23:39:02 +08:00 · 3693 次点击
    这是一个创建于 1965 天前的主题,其中的信息可能已经有所发展或是发生改变。
    <button
        v-for="catalog in catalogs"
        :key="catalog.id"
        :class="{'active': current_catalog==catalog.name}"
        @click="change(catalog.name)"
        >
        {{ catalog.name }}
    </button>
    
    data() {
        return {
            catalogs: [{id: 999, name: '不限类目'}],
            current_catalog: '不限类目'
        }
    },
    
    created() {
        $axios({
            method: 'get',
            url: '/api/catalog'
        })
        .then( resp=> {
        	this.catalogs = this.catalogs.concat(resp.data.data)
        })
    },
    
    methods: {
        change(val) {
            this.current_catalog = val
        },
    }
    

    之前问过一次, 补上代码. 需要 class="active"生效, 如果 catalogs 一开始写死, 就没问题, 但如果用请求的数据, 就没辙了. 不知道怎么解决?

    28 条回复    2019-08-06 16:27:49 +08:00
    donething
        1
    donething  
       2019-08-05 00:04:47 +08:00
    使用 Vue.set()向数组添加新元素,看看
    xxx749
        2
    xxx749  
       2019-08-05 00:10:00 +08:00 via Android
    Vue 的数组变异方法里没有 concat,试试 this.catalogs = [...this.catalogs.concat, ...resp.data.data]
    luckyx
        3
    luckyx  
       2019-08-05 05:08:00 +08:00 via iPhone
    :class="'active:'+current_catalog==catalog.name"
    Exceptionluo
        4
    Exceptionluo  
       2019-08-05 09:06:32 +08:00
    看代码应该没问题呀 建议检查下返回的数据结构
    aria955
        5
    aria955  
       2019-08-05 09:54:56 +08:00
    watch catelogs 试试看
    xutao881
        6
    xutao881  
       2019-08-05 10:35:50 +08:00
    写了测试方法没问题,建议放一下返回数据结构
    aoscici2000
        7
    aoscici2000  
    OP
       2019-08-05 11:04:06 +08:00
    @xutao881 那就相当奇怪了... 数据结构没问题的, button 里面的内容也显示正常
    xutao881
        8
    xutao881  
       2019-08-05 11:07:47 +08:00
    @aoscici2000 贴一下 concat 之后的 catalogs 看看
    aoscici2000
        9
    aoscici2000  
    OP
       2019-08-05 11:25:05 +08:00
    @xutao881 [{"id":999,"name":"不限类目"},{"id":10007,"name":"游泳"},{"id":10008,"name":"瑜伽"}......] ,直接从 Vue devtools 复制的
    no1xsyzy
        10
    no1xsyzy  
       2019-08-05 12:30:27 +08:00
    no1xsyzy
        11
    no1xsyzy  
       2019-08-05 12:35:21 +08:00
    考虑:HTML/JS 预处理器的存在导致代码语义变化、各库版本(以 lock 文件为标准)、
    aoscici2000
        12
    aoscici2000  
    OP
       2019-08-05 14:08:02 +08:00
    .then(resp => {
    this.$set(this, 'catalogs', resp.data.data)
    })
    也无效
    SilentDepth
        13
    SilentDepth  
       2019-08-05 14:19:08 +08:00
    从贴出来的代码上看,没问题。我现在只能怀疑是你的 Array.prototype.concat 有问题。

    @aoscici2000 #12 this.$set( ) 不能这么用,应该是:
    this.$set(this.catalogs, 1, resp.data.data[0])
    // ...
    aoscici2000
        14
    aoscici2000  
    OP
       2019-08-05 14:40:29 +08:00
    @SilentDepth 文档里#Vue.set(object, key, value) 不是这样的? 我就直接不要原本定死的那个数据了, 数据添加也能正常.

    this.$set(this.catalogs, 1, resp.data.data[0]) 这个倒是有点看不懂什么意思了, 1 是什么意思?
    aoscici2000
        15
    aoscici2000  
    OP
       2019-08-05 14:41:23 +08:00
    @no1xsyzy 晕, 这难道我在组件里用的就无效...
    SilentDepth
        16
    SilentDepth  
       2019-08-05 14:43:27 +08:00   ❤️ 1
    @aoscici2000 #14 Vue 官方文档:

    注意对象( Vue.set( ) 的 target 参数)不能是 Vue 实例,或者 Vue 实例的根数据对象。

    1 是 this.catalogs 的属性名。由于它是个数组,所以属性名就是数字的形式,也就是数组下标。
    jtwor
        17
    jtwor  
       2019-08-05 15:19:09 +08:00
    (current_catalog==catalog.name)
    aoscici2000
        18
    aoscici2000  
    OP
       2019-08-05 15:24:07 +08:00
    @SilentDepth 得到的数据正常, get, set 什么的属性都有, :class 就是不工作, 放弃了

    .then(resp => {
    let list = resp.data.data
    for (let i=0, len=list.length; i<len; i++) {
    this.$set(this.catalogs, i+1, list[i])
    }
    })
    hellomimi
        19
    hellomimi  
       2019-08-05 15:26:38 +08:00
    代码没问题,console.log(resp)看看返回数据
    hellomimi
        20
    hellomimi  
       2019-08-05 15:29:06 +08:00
    .active 的样式、css 权重检查一下
    rain0002009
        21
    rain0002009  
       2019-08-05 15:38:40 +08:00
    你把 current_catalog==catalog.name 展示出来 到底是 true 还是 false
    no1xsyzy
        22
    no1xsyzy  
       2019-08-05 15:43:00 +08:00
    如果确实替换 data() > return object > 'catalogs' 和 create() 就能解决的话(请先确认)考虑:
    1. :class 内容是否写错?= 与 ==,或者 === 试一下
    2. class 确认没有正确填上,而不是 #20 猜测的那样 class 填上了样式没正确应用?
    3. Promise.resolve() 替换一下试试?
    4. 将 active 的判断转化为 ((x,y)=>{console.log(x,y,x==y);return x==y})(current_catalog,catalog.name),来 hook 进去打一下 log
    yang137162692
        23
    yang137162692  
       2019-08-05 17:13:05 +08:00
    this.catalogs = this.catalogs.concat(resp.data.data) 更新数组 使用 concat 不会触发 vue 更新
    hellomimi
        24
    hellomimi  
       2019-08-05 17:39:46 +08:00
    mikoshu
        25
    mikoshu  
       2019-08-05 17:48:53 +08:00
    数组用 push 进去 才会监听到变动
    wlor
        26
    wlor  
       2019-08-06 09:24:36 +08:00
    Vue 2.0 是基于 Object.defineProperty 对对象实现“响应式化”,而对于数组,Vue 提供的方法是重写 push、pop、shift、unshift、splice、sort、reverse 这七个数组方法 你用 concat 是监听不了的 要用的话用 Vue,$set 你的$set 用错了 而且不建议你用 concat 方法 性能很差
    no1xsyzy
        27
    no1xsyzy  
       2019-08-06 14:53:09 +08:00
    @wlor @yang137162692 @mikoshu
    所以说现在我很怀疑 v2 前端水平
    Array::concat 不是变异方法,调用完原数组不变的
    触发变动的是对 this.catalogs 全量赋值,不然我 #10 的例子和 #24 的例子为什么能正常工作?
    另一方面印证,楼主仅仅是 :class 不能正常工作,而不是 v-for,所以可见给 this.catalogs 赋值正常工作了。
    yang137162692
        28
    yang137162692  
       2019-08-06 16:27:49 +08:00
    @no1xsyzy 嘿嘿,不好意思,不会再随意回复了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2846 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 08:05 · PVG 16:05 · LAX 00:05 · JFK 03:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.