我用v-for呈现了一个电子邮件列表,管理员可以删除这些电子邮件。我需要根据删除电子邮件的过程是否正在进行,将"正在加载"状态设置为true或false。我知道如果我使用了一个对象,我可以添加一个加载到对象中的属性,并在我的remove函数中设置该状态,但是否可以设置我的一个列表项的状态,同时将列表保持为字符串数组?
data: {
admins: [foo@gmail.com, bar@gmail.com]
}
<div class="admin-row" :class="{active : editAdmins}" v-for="(admin, index) in admins" :key="index">
<div class="remove-admin">
<fa v-if="!loading" @click="removeAdmin(admin)" icon="minus-circle"/>
<fa v-if="loading" class="remove-admin-loader" icon="spinner" spin/>
</div>
</div>
因此,基本上我想在单击removeAdmin时将加载变量设置为true,但我需要在v-for语句中确定变量的作用域。
您似乎必须使用与admins数组保持相同元素顺序的加载变量创建另一个数组,然后设置loads[index]变量,或者将admins数组更改为对象数组,而不是字符串数组。在这种情况下,管理员的数组应该是这样的:
admins: [
{mail: 'foo@gmail.com', loading: false},
{mail: 'bar@gmail.com', loading: true}
]
这里的问题是数组中的内容是字符串,不能直接将属性添加到字符串中。
为了解决这个问题,我们需要创建一个简单的类,它将string
封装成object
,秘密在于toString
方法。
class StringObject {
constructor(value) {
this.value = value;
}
toString() {
return this.value;
}
}
在removeAdmin
上,添加一个条件将字符串转换为StringObject
:
if (!(this.admins[index] instanceof StringObject)) {
this.$set(this.admins, index, new StringObject(this.admins[index]))
}
现在,在模板中,您可以将其用作:
{{ admin.toString() }}
只需在此处检查整个工作样本:https://jsfiddle.net/eywraw8t/235969/
虽然这可以回答您的问题,但我不推荐这种方法,因为它只会增加代码的复杂性,而且看起来不像basic
最好的方法是clearly
将组件中使用的所有变量声明为data
属性。因为这将使您更容易理解组件
另一个提示:
在处理列表时,避免将整个对象传递到方法中。在示例代码中,将整个admin
对象传递到removeAdmin
方法中。使用index
会更容易、更快。您可以在上面的JS fiddle示例中看到我们如何使用索引处理列表,尤其是使用删除。
当删除一个项时,我们只使用splice()
并将index
传递给它
this.admins.splice(index, 1);
但是,如果要使用对象引用,则需要首先在数组中找到该对象的索引,这会导致执行额外的步骤,而且速度较慢。
这是最简单的方法,因为我遇到过同样的问题,而且考虑得很广泛。从未从任何人那里找到解决方案。
在v-for中创建一个组件文件,向下传递props,您可以在data((或setup((中添加状态,它将为数组中的每个v-for项创建一个新状态。