aoscici2000
V2EX  ›  Vue.js

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

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

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

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

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

    1 是 this.catalogs 的属性名。由于它是个数组,所以属性名就是数字的形式,也就是数组下标。
    jtwor
        17
    jtwor  
       Aug 5, 2019
    (current_catalog==catalog.name)
    aoscici2000
        18
    aoscici2000  
    OP
       Aug 5, 2019
    @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  
       Aug 5, 2019
    代码没问题,console.log(resp)看看返回数据
    hellomimi
        20
    hellomimi  
       Aug 5, 2019
    .active 的样式、css 权重检查一下
    rain0002009
        21
    rain0002009  
       Aug 5, 2019
    你把 current_catalog==catalog.name 展示出来 到底是 true 还是 false
    no1xsyzy
        22
    no1xsyzy  
       Aug 5, 2019
    如果确实替换 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  
       Aug 5, 2019
    this.catalogs = this.catalogs.concat(resp.data.data) 更新数组 使用 concat 不会触发 vue 更新
    hellomimi
        24
    hellomimi  
       Aug 5, 2019
    mikoshu
        25
    mikoshu  
       Aug 5, 2019
    数组用 push 进去 才会监听到变动
    wlor
        26
    wlor  
       Aug 6, 2019
    Vue 2.0 是基于 Object.defineProperty 对对象实现“响应式化”,而对于数组,Vue 提供的方法是重写 push、pop、shift、unshift、splice、sort、reverse 这七个数组方法 你用 concat 是监听不了的 要用的话用 Vue,$set 你的$set 用错了 而且不建议你用 concat 方法 性能很差
    no1xsyzy
        27
    no1xsyzy  
       Aug 6, 2019
    @wlor @yang137162692 @mikoshu
    所以说现在我很怀疑 v2 前端水平
    Array::concat 不是变异方法,调用完原数组不变的
    触发变动的是对 this.catalogs 全量赋值,不然我 #10 的例子和 #24 的例子为什么能正常工作?
    另一方面印证,楼主仅仅是 :class 不能正常工作,而不是 v-for,所以可见给 this.catalogs 赋值正常工作了。
    yang137162692
        28
    yang137162692  
       Aug 6, 2019
    @no1xsyzy 嘿嘿,不好意思,不会再随意回复了
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2797 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 62ms · UTC 09:26 · PVG 17:26 · LAX 02:26 · JFK 05:26
    ♥ Do have faith in what you're doing.