我使用以下代码生成列表:
<li class="list-group-item border" v-for="command in commands" :key="command">
<div v-if="!command.args">
<h3>{{ command.name }}</h3>
<small>{{ command.desc }}</small>
</div>
<div v-else>
<button @click="toggleActive">{{ command.name }}</button>
<small>{{ command.desc }}</small>
<div class="args" v-if="active" v-for="(argDesc, argName) in command.args" :key="argName, argDesc">
<hr>
<p>{{ argName }}</p>
<small>{{ argDesc }}</small>
</div>
</div>
</li>
使用以下数据:
commands: {
foo: { name: "foo", desc: "bar" },
lorem: {
name: "lorem",
desc: "ipsum",
args: {
place: "holder"
}
},
和方法:
methods: {
toggleActive: function(event) {
let clickedButton = event.currentTarget;
clickedButton.classList.toggle("active");
if (this.active) {
this.active = false;
} else if (!this.active) {
this.active = true;
}
}
}
如果有一个更优雅的解决方案,我想知道,但我真正的问题是如何才能使点击按钮而不是所有生成的按钮触发onclick事件?< / p>
答案 0 :(得分:3)
您目前的整个实例都有一个 active
属性。
一种解决方案是为每个active
添加command
属性,然后将其切换为:
@click="toggleActive($event, command)"
您的方法现在应设置command.active
,而不是this.active
:
methods: {
toggleActive: function(event, command) { // added command arg
// removed manual class toggling (see "Bonus" below)
if (command.active) { // command.active instead of this.active
command.active = false; // command.active instead of this.active
} else if (!command.active) {
Vue.set(command, 'active', true); // using `Vue.set()` because `active`
} // was not initially in `data()`
}
}
最后,您的v-if
应该引用每个命令:v-if="command.active"
。
加分:使用Vue,您不必直接执行clickedButton.classList.toggle("active");
。您只需绑定class
属性::class="{active: command.active}"
。
演示如下:
new Vue({
el: '#app',
data: {
commands: {
foo: { name: "foo", desc: "bar" },
lorem: {
name: "lorem",
desc: "ipsum",
args: {
place: "holder"
}
},
aaa: {
name: "aaa",
desc: "bbb",
args: {
place: "ccc"
}
},
}
},
methods: {
toggleActive: function(event, command) {
// removed manual class toggling in favor of :class="{active: command.active}"
if (command.active) {
command.active = false;
} else if (!command.active) {
Vue.set(command, 'active', true);
}
}
}
})
&#13;
.active { color: red }
&#13;
<script src="https://unpkg.com/vue"></script>
<div id="app">
<li class="list-group-item border" v-for="command in commands" :key="command.name">
<div v-if="!command.args">
<h3>{{ command.name }}</h3>
<small>{{ command.desc }}</small>
</div>
<div v-else>
<button @click="toggleActive($event, command)" :class="{active: command.active}">{{ command.name }}</button>
<small>{{ command.desc }}</small>
<div class="args" v-if="command.active" v-for="(argDesc, argName) in command.args" :key="argName, argDesc">
<hr>
<p>{{ argName }}</p>
<small>{{ argDesc }}</small>
</div>
</div>
</li>
</div>
&#13;
如果您不想更改每个command
,另一个选择是将active
转换为旗帜地图(而不是仅仅一个旗帜):
new Vue({
el: '#app',
data: {
active: {}, // should be an object
commands: {
foo: { name: "foo", desc: "bar" },
lorem: {
name: "lorem",
desc: "ipsum",
args: {
place: "holder"
}
},
aaa: {
name: "aaa",
desc: "bbb",
args: {
place: "ccc"
}
},
}
},
methods: {
toggleActive: function(event, command) {
// removed manual class toggling in favor of :class="{active: active[command.name]}"
if (this.active[command.name]) {
this.active[command.name] = false;
} else if (!this.active[command.name]) {
Vue.set(this.active, command.name, true);
}
}
}
})
&#13;
.active { color: red }
&#13;
<script src="https://unpkg.com/vue"></script>
<div id="app">
<li class="list-group-item border" v-for="command in commands" :key="command.name">
<div v-if="!command.args">
<h3>{{ command.name }}</h3>
<small>{{ command.desc }}</small>
</div>
<div v-else>
<button @click="toggleActive($event, command)" :class="{active: active[command.name]}">{{ command.name }}</button>
<small>{{ command.desc }}</small>
<div class="args" v-if="active[command.name]" v-for="(argDesc, argName) in command.args" :key="argName, argDesc">
<hr>
<p>{{ argName }}</p>
<small>{{ argDesc }}</small>
</div>
</div>
</li>
</div>
&#13;