javascript - Vue.js - 每组仅单击一个按钮即可生成动态按钮

标签 javascript html 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>

That worked

第一次需要它时,它起作用了,但当我第二次问一个有 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 属性,但这是行不通的。

另一个问题是,如果修改答案,它将影响所有问题,而不仅仅是一个问题。因为它们都共享同一个数组。

相反,我会修改您的 examples 对象,以包含对象而不是字符串。 该对象将包含用户选择的问题和答案。 这样,每个问题都会有一个具体的答案,并且用户只能选择一个答案,因为它将覆盖旧值。

注意: @clickv-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>

您可以向 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>

关于javascript - Vue.js - 每组仅单击一个按钮即可生成动态按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61006044/

相关文章:

javascript - 在纯 Javascript 中按类隐藏元素

javascript - ruby 变量在 driver.execute_script 之后返回 nil

javascript - 使用子列表 javascript 遍历列表

javascript - 将Youtube音频转换为数字

javascript - 如何避免简单形式的 NaN 错误?

html - 不使用JS可以实现这种灵活的布局吗?

javascript - 在 TextArea 中显示 xml

vue.js - 如何使用插槽将 Prop 从 parent 传递给 child -vuejs

laravel - php artisan ui vue get ErrorException 无法打开流 : No such file or directory

javascript - Vue 计算属性未更新 - 未定义数据属性的奇怪行为