javascript - Vue.js - 每组仅单击一个按钮以生成动态按钮
问题描述
我在一个网站上有五个问题,每个问题有 4 个答案。每个问题只能点击一个按钮。
我怎样才能做到这一点?
new Vue({
el: '#app',
data: {
answers: {},
currentQuestion: {
examples: {
A: 'Lack zum Lackieren der Computergehäuse',
B: 'Elektrische Energie für die Montagewerkzeuge',
C: 'Silizium zur Herstellung der CPU',
D: 'Schrauben zum Befestigen von Bauteilen',
E: 'Zugekaufte Computergehäuse aus Stahlblech'
},
answers: {
'1': 'Rohstoff',
'2': 'Fremdbauteil',
'3': 'Hilfsstoff',
'4': 'Betriebsstoff'
},
rights: {
A: 3,
B: 4,
C: 1,
D: 3,
E: 2
}
}
},
methods: {
selectedOneAnswerButton(index) {
Array.from(this.answers).forEach(answer => (answer.active = false));
let answer = this.answers[index];
answer.active = !answer.active;
this.$set(this.answers, index, answer);
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<div id="app">
<div
v-bind:key="index"
v-for="(example, index) in currentQuestion.examples"
class="row"
>
<div class="col-md-12">
<p class="p-3 mb-2 bg-dark text-white">{{ example }}</p>
</div>
<div
v-bind:key="index"
v-for="(answer, index) in currentQuestion.answers"
class="col-md-6"
>
<p>
<button
v-bind:class="{
'btn-primary': answer.active,
'btn-secondary': !answer.active
}"
v-on:click="selectedOneAnswerButton(index)"
class="btn btn-lg btn-block"
>
{{ answer }}
</button>
</p>
</div>
</div>
</div>
这在我第一次需要它时起作用,但在我第二次问一个有 4 个答案的简单问题时它就不起作用了……当然在目前的情况下,有四个问题和四个可能的答案。
这是 JavaScript 中的示例,我如何在不更改数据的情况下管理它。
var currentQuestion = {
examples: {
"A": "Lack zum Lackieren der Computergehäuse",
"B": "Elektrische Energie für die Montagewerkzeuge",
"C": "Silizium zur Herstellung der CPU",
"D": "Schrauben zum Befestigen von Bauteilen",
"E": "Zugekaufte Computergehäuse aus Stahlblech"
},
answers: {
"1": "Rohstoff",
"2": "Fremdbauteil",
"3": "Hilfsstoff",
"4": "Betriebsstoff"
},
rights: {
"A": 3,
"B": 4,
"C": 1,
"D": 3,
"E": 2
}
};
function selectAnswer(id) {
$(id).addClass("btn-primary");
$(id).removeClass("btn-secondary");
}
function deselectAnswer(id) {
$(id).addClass("btn-secondary");
$(id).removeClass("btn-primary");
}
var root = document.getElementById("container");
var mutlipleequestionscreen = document.createElement("div");
buildMultipleQuestionScreen();
// LAYOUT
function buildMultipleQuestionScreen() {
console.log("buildMultipleQuestionScreen");
mutlipleequestionscreen.id = "multiple-question-screen";
mutlipleequestionscreen.className = "jumbotron question";
root.appendChild(mutlipleequestionscreen);
var div = document.createElement("div");
div.id = "multiple-questions";
var h2 = document.createElement("h2");
h2.textContent = "Frage ";
var span = document.createElement("span");
span.className = "multiple-question-number";
span.textContent = currentQuestion.id;
var div2 = document.createElement("div");
div2.className = "situation p-3 mb-2 bg-info text-white";
var p = document.createElement("p");
p.className = "multiple-question-situation";
p.textContent = currentQuestion.situation;
var p2 = document.createElement("p");
p2.className = "multiple-question-description";
p2.textContent = currentQuestion.description;
var p3 = document.createElement("p");
p3.className = "multiple-question-text";
p3.textContent = currentQuestion.question;
var p4 = document.createElement("p");
p4.className = "multiple-question-exercise";
p4.textContent = currentQuestion.exercise;
var p5 = document.createElement("p");
p5.className = "multiple-question-note";
p5.textContent = currentQuestion.note;
mutlipleequestionscreen.appendChild(div);
div.appendChild(h2);
h2.append(span);
div.appendChild(div2);
div2.appendChild(p);
div.appendChild(p2);
div.appendChild(p3);
div.appendChild(p4);
div.appendChild(p5);
var letter = "";
for(var i = 0; i < Object.keys(currentQuestion.examples).length; i++)
{
var row = document.createElement("div");
row.className = "row";
var div3 = document.createElement("div");
div3.className = "col-md-12";
var p6 = document.createElement("p");
p6.className = "p-3 mb-2 bg-dark text-white";
p6.textContent = Object.keys(currentQuestion.examples)[i] + " : ";
var span2 = document.createElement("span");
letter = Object.keys(currentQuestion.examples)[i];
span2.id = "multiple-question-example-" + letter.toLowerCase();
span2.textContent = currentQuestion.examples[Object.keys(currentQuestion.examples)[i]];
div.appendChild(row);
row.appendChild(div3);
div3.appendChild(p6);
p6.appendChild(span2);
var row2 = document.createElement("div");
row2.className = "row";
for(var j = 1; j <= Object.keys(currentQuestion.answers).length; j++)
{
if(j % 2 != 0)
{
div.appendChild(row2);
}
var div4 = document.createElement("div");
div4.className = "col-md-6";
var p7 = document.createElement("p");
var button = document.createElement("button");
button.id = "multiple-question-answer-" + letter.toLowerCase() + "-" + j + "-btn"
button.className = "answer answer-btn answer-" + letter.toLowerCase() + "-btn answer-" + j + "-btn btn btn-secondary btn-lg btn-block";
var span3 = document.createElement("span");
span3.className = "multiple-question-answer-" + j;
span3.textContent = Object.keys(currentQuestion.answers)[j - 1] + ": " + currentQuestion.answers[j];
button.addEventListener("click", function() {
selectAnswer(this);
var letterTmp = this.id.split('-')[3];
$(".answer-" + letterTmp + "-btn").not(this).each(function() {
deselectAnswer(this);
});
console.log(this.id);
});
row2.appendChild(div4);
div4.appendChild(p7);
p7.appendChild(button);
button.appendChild(span3);
}
}
var row3 = document.createElement("div");
row3.className = "row";
var div5 = document.createElement("div");
div5.className ="col-md-10";
var div6 = document.createElement("div");
div6.className = "col-md-2";
var p8 = document.createElement("p");
var button2 = document.createElement("button");
button2.id = "multiple-question-answer-commit-btn";
button2.className = "answer-commit-btn btn btn-primary btn-lg btn-block";
var span4 = document.createElement("span");
span4.className = "multiple-question-commit-text";
span4.textContent = "Antworten";
// MULTIPLE QUESTION ANTWORTEN BUTTON
button2.addEventListener("click", function() {
// IN DEN GLOBALEN EINSTELLUNGEN
// .answer-commit-btn
answerCommitButton();
});
var p9 = document.createElement("p");
var button3 = document.createElement("button");
button3.id ="multiple-question-continue-btn";
button3.className = "continue-btn btn btn-primary btn-lg btn-block";
button3.style = "display: none;";
var span5 = document.createElement("span");
span5.textContent = "Weiter";
// MULTIPLE QUESTION WEITER BUTTON
button3.addEventListener("click", function() {
var node = document.getElementById("container");
var child = document.getElementById("multiple-question-screen");
var child2 = document.getElementById("multiple-questions");
node.removeChild(child);
child.removeChild(child2);
// IN DEN GLOBALEN EINSTELLUNGEN
continueButton();
});
div.appendChild(row3);
row3.appendChild(div5);
row3.appendChild(div6);
div6.appendChild(p8);
p8.appendChild(button2);
button2.appendChild(span4);
div6.appendChild(p9);
p9.appendChild(button3);
button3.appendChild(span5);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>
<div id="container">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="example.js"></script>
</body>
</html>
可以在 VUE.JS 中执行此操作而不更改我的数据吗?
解决方案
问题是您的答案是一个字符串,但您将它视为一个对象。试图将active
属性添加到它是行不通的。
另一个问题是,如果您修改answers
,它将影响所有问题,而不仅仅是一个问题。因为它们都共享相同的数组。
相反,我会修改您的examples
对象,以包含对象而不是字符串。该对象将包含用户选择的问题和答案。这样一来,您将对每个问题都有一个特定的答案,并且用户只能选择一个,因为它会覆盖旧值。
注: @click
是 的简写v-on:click
,:class
是 的简写v-bind:class
选项1:
new Vue({
el: '#app',
data: {
answers: {},
currentQuestion: {
examples: {
A: {
question: 'Lack zum Lackieren der Computergehäuse',
pickedAnswer: null
},
B: {
question: 'Elektrische Energie für die Montagewerkzeuge',
pickedAnswer: null
},
C: {
question: 'Silizium zur Herstellung der CPU',
pickedAnswer: null
},
D: {
question: 'Schrauben zum Befestigen von Bauteilen',
pickedAnswer: null
},
E: {
question: 'Zugekaufte Computergehäuse aus Stahlblech',
pickedAnswer: null
}
},
answers: {
'1': 'Rohstoff',
'2': 'Fremdbauteil',
'3': 'Hilfsstoff',
'4': 'Betriebsstoff'
},
rights: {
A: 3,
B: 4,
C: 1,
D: 3,
E: 2
}
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<div id="app">
<div
:key="index"
v-for="(example, index) in currentQuestion.examples"
class="row"
>
<div class="col-md-12">
<p class="p-3 mb-2 bg-dark text-white">{{ example.question }}</p>
</div>
<div
:key="index"
v-for="(answer, index, key) in currentQuestion.answers"
class="col-md-6"
>
<p>
<button
:class="{
'btn-primary': example.pickedAnswer == key,
'btn-secondary': example.pickedAnswer != key
}"
@click="example.pickedAnswer = key"
class="btn btn-lg btn-block"
>
{{ answer }}
</button>
</p>
</div>
</div>
</div>
examples
您可以向对象添加新属性,而不是将您的对象转换为currentQuestion
对象。我pickedAnswers
在示例中调用了它,该对象将包含用户选择的答案。
选项 2:
new Vue({
el: '#app',
data: {
answers: {},
currentQuestion: {
examples: {
A: 'Lack zum Lackieren der Computergehäuse',
B: 'Elektrische Energie für die Montagewerkzeuge',
C: 'Silizium zur Herstellung der CPU',
D: 'Schrauben zum Befestigen von Bauteilen',
E: 'Zugekaufte Computergehäuse aus Stahlblech'
},
pickedAnswers: {
A: null,
B: null,
C: null,
D: null,
E: null,
},
answers: {
'1': 'Rohstoff',
'2': 'Fremdbauteil',
'3': 'Hilfsstoff',
'4': 'Betriebsstoff'
},
rights: {
A: 3,
B: 4,
C: 1,
D: 3,
E: 2
}
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<div id="app">
<div
:key="index"
v-for="(example, questionKey, index) in currentQuestion.examples"
class="row"
>
<div class="col-md-12">
<p class="p-3 mb-2 bg-dark text-white">{{ example }}</p>
</div>
<div
:key="index"
v-for="(answer, key) in currentQuestion.answers"
class="col-md-6"
>
<p>
<button
:class="{
'btn-primary': currentQuestion.pickedAnswers[questionKey] == key,
'btn-secondary': currentQuestion.pickedAnswers[questionKey] != key
}"
@click="currentQuestion.pickedAnswers[questionKey] = key"
class="btn btn-lg btn-block"
>
{{ answer }}
</button>
</p>
</div>
</div>
</div>
推荐阅读
- nagios - 是否可以将服务的执行限制在特定的时间范围内?
- python - 如何从一些 python 脚本中调用函数,这些函数的名称可以在另一个 python 脚本中更改?
- python - 可以直接将 xpath 复制并粘贴到漂亮的汤解析器中,还是必须对其进行修改?
- php - Issue in using multiple databases in laravel 5.2
- javascript - 如何使用leaflet.js(附截图)实现以下地图功能?
- bash - 如何在 Linux 中循环访问变量值?
- rxjs - Rxjs:执行代码并在 Observable 完成时发出值
- javascript - 在 Javascript 中更新数组元素
- python - 如何根据条件解释过滤行?
- bash - 在 bash 文件中使用带有 shell 扩展的 grep 和 awk,引用转义问题