Vue.js 单击使用v-for创建的组件时,将类添加到特定的父div

Vue.js 单击使用v-for创建的组件时,将类添加到特定的父div,vue.js,v-for,Vue.js,V For,我是vuejs新手,这就是我想要做的: 我有一个组件列表,每个组件都在一个div中。现在,如果我对该组件执行某些操作(即单击它)。我想向父div添加一个类。这就是我到目前为止所做的,代码被简化了,只是为了展示我想用一个简单的案例做什么 我的app.vue: <div class="toggle-box" v-for="(name, index) in names" :class="classActive" :key="index"> <app-comp :myName=

我是vuejs新手,这就是我想要做的: 我有一个组件列表,每个组件都在一个div中。现在,如果我对该组件执行某些操作(即单击它)。我想向父div添加一个类。这就是我到目前为止所做的,代码被简化了,只是为了展示我想用一个简单的案例做什么

我的app.vue:

<div class="toggle-box" v-for="(name, index) in names" :class="classActive" :key="index">
    <app-comp :myName="name" :myIndex="index" @someEvent="doSomething"></app-counter>
</div>
data() {
    classActive: '',
    names: ['alpha', 'beta', 'gamma']
},
methods: {
    doSomething() {
        this.classActive === '' ? this.classActive = 'is-active': this.classActive='';
    }
}

数据(){
类活动:“”,
名称:['alpha','beta','gamma']
},
方法:{
doSomething(){
this.classActive==''?this.classActive=''处于活动状态:this.classActive='';
}
}
组成部分:

<div>
    <button @click="toggle">{{ myName }} - {{ myIndex }}</button>
</div>

props: ['myName', 'myIndex'],
methods: {
    toggle() {
        this.$emit('someEvent', index);
    }
}

{{myName}}-{{myIndex}
道具:['myName','myIndex'],
方法:{
切换(){
此.$emit('someEvent',索引);
}
}
它的作用:它创建了3个带有“切换框”的div,这个类中有一个带有标签“name-index”的按钮。当我点击一个按钮时,它会发出“someEvent”——带有索引的事件。父级侦听此事件,并使用“切换框”类在div上切换类“处于活动状态”。现在的问题是,当我点击一个按钮时,它会将类添加到所有3个div中。可能是因为vuejs的3个div之间没有区别。我知道我可以将索引附加到事件并在父级中使用$event调用它,但是我如何使用它呢?或者有没有更好的方法来实现我想要的


感谢您的帮助。

有几种不同的方法可以实现这一点,但我认为首先要考虑的是您希望如何将其表示为数据,而不是如何将其显示在UI中。因此,先建模,后查看

大概在这些活动项被选中后,您会想对它们做些什么。我会把重点放在这一点上,而不是强调它们的问题。突出显示将相对轻松地消失

为了便于讨论,让我们假设一个活动项数组是您试图实现的目标的合适模型。可能不是,但这是一个简单的例子

因此:

这里没有提到类,因为我们不担心UI问题,我们正在尝试对底层数据建模

对于
切换
方法,我更倾向于发出
名称
,而不是
索引
,但您更适合判断哪个更好地表示数据。例如,它将是
name

methods: {
    toggle() {
        this.$emit('someEvent', this.myName);
    }
}
然后在父组件中,我们将在发出事件时从数组中添加/删除
名称。对于这一点,其他数据结构可能更好,最后我将回到这一点

methods: {
    doSomething(name) {
        if (this.activeNames.includes(name)) {
            this.activeNames = this.activeNames.filter(item => item !== name);
        } else {
            this.activeNames.push(name);
        }
    }
}
现在我们有了一个包含活动名称的数组,我们可以使用它来派生那些包装器div的类

<div
    class="toggle-box"
    v-for="(name, index) in names"
    :class="{'is-active': activeNames.includes(name)}"
    :key="index"
>
在许多方面,对于这个特定的示例,这是一个更容易使用的结构,但是我们最终会将名称复制为属性键。如果我们不这样预先填充它,我们最终可能会遇到反应性问题(尽管这些问题可以使用
$set
解决)

另一种选择是首先使用对象来表示名称:

data() {
    return {
        names: [
            {name: 'alpha', active: false},
            {name: 'beta', active: false},
            {name: 'gamma', active: false}
        ]
    }
}
这种数据结构对于您的用例是否有意义,我真的无法判断


更新:

根据您在评论中所说的,我倾向于创建另一个组件来表示切换框。每个组件都可以存储自己的
active
状态,而不是将它们全部保存在父组件上。然后,您的
v-for
将直接创建此新组件的实例。根据具体情况,此新组件可能会合并到原始组件中


这里还有各种各样的其他考虑因素,使得给出一个明确的答案非常困难。如果活动状态需要在切换框组件之外知道,那么它与仅为内部状态的情况完全不同。如果一次只能打开一个切换框(如手风琴),那么这同样很棘手,因为内部状态是不够的。

不确定为什么要将
classActive
作为应用程序的属性而不是组件。你是什么意思?我知道这可能不是最好的方法,请随意改变:-)首先。谢谢你的回答。在我的项目中,组件要复杂得多。让我们说一个显示一些信息的“框”。通过单击组件,该框将打开,再次单击时将关闭。我只想向togglebox div添加一些样式,以显示该框当前处于打开状态。正如我所说,我是vuejs新手,所以我不知道是否有更好的方法来实现这一点,我的想法是在其中添加一个“is active”类。但由于切换框的数量是动态的,因此很难预填充对象。this.activeNames=this.activeNames.filter(item=>item!==name);这是一个很大的帮助。我已经更新了我的答案,但问题的核心仍然是以正确的方式存储数据。一旦你得到了正确的数据形状和位置,剩下的就很容易了。根据您的评论,与复杂的数据结构相比,围绕组件边界移动可能是一个更好的选择。
data() {
    return {
        names: ['alpha', 'beta', 'gamma'],
        activeNames: {
            alpha: false,
            beta: false,
            gamma: false
        }
    }
}
data() {
    return {
        names: [
            {name: 'alpha', active: false},
            {name: 'beta', active: false},
            {name: 'gamma', active: false}
        ]
    }
}