Vue Js - 动态绑定一个 class 并在满足条件时执行函数

Vuejs - Dinamically bind a class and execute function if a condition is meet

我正在尝试为我的 vue 应用程序中的三个小问题找到解决方案。 第一个是关于 class 绑定。我有一张 bootstrao 卡,可以显示问题和相关答案。用户点击单选输入后,答案被保存,其他选项被禁用。

我正在动态检查用户答案是否正确,但我无法动态更改卡片边框的 class。我想在给出答案之前有一个黑色边框,然后如果正确则将边框 class 更改为 border-successborder-danger 如果错误。我试过这段代码但没有成功,如果没有给出答案,边框也会有 border-danger class。

<div class="card text-dark bg-light border-secondary shadow mt-3 mb-3" :class="[userAnswers[qindex] === correctAnswers[qindex] && answered[qindex] ? 'border-success' : 'border-danger']">

应用 UI 的另一个小问题是卡片页脚。我添加了一个卡片页脚,在回答显示的问题之前它是不可见的。它会显示正确答案,但我注意到如果给出正确答案,它会出现图形故障并出现然后消失。

<div class="card-footer bg-transparent border-success fw-bold" v-show="userAnswers[qindex] !== correctAnswers[qindex]">La risposta correttà è: {{ correctAnswers[qindex] }}</div>

为了尝试修复,我测试了 v-if 和实际的 v-show,我还用 css 在元素上添加了一个过渡,但似乎不起作用

.card-footer {
  transition: ease-in .3s;
}

最后也是最重要的问题是条件检查。当用户回答了所有可用问题时,我想显示一个模式。我试图在 vue 的挂载钩子中添加一个 if() 语句,但它永远不会被触发。我还尝试在 axios 调用的 .then() 回调中调用该方法,该方法将检查每个问题的答案但没有成功。

export default {
  name: 'App',
  data(){
    return {
      isLoading: true,
      showResult: false,
      elaspedTime: null,
      questions: [],
      answered: {},
      userAnswers: [],
      correctAnswers: []
    }
  },
  mounted(){
    this.init();
    // statement will be never evalued 
    if( this.answered.length === this.questions.length ){
      this.quizResults();
    }
  },
  methods: {
    init(){
      axios({
        method: 'GET',
        url: 'http://localhost:8990/init'
      }).then( (res) => {
        this.questions = [];
        this.questions = res.data;
        console.log(this.questions);
        this.isLoading = false;
      });
    },
    checkAnswer(qindex, index, value){
      // console.log(qindex, index, value);
      this.answered[qindex] = true;
      this.userAnswers.push(value);
      axios({
        method: 'POST',
        url: 'http://localhost:8990/answercheck',
        data: {
          questionIndex: index,
          choice: value
        }
      }).then( (res) => {
        console.log(res.data);
        this.correctAnswers.push(res.data.correctAnswer);
        
      });
    },
    quizResults(){
// some logics after all the questions are answered 
      console.log('Results');
    }
  }
}

谁能帮我找到解决这些问题的方法?谢谢。

所以你在这里有 3 个问题。

关于您的第一个问题

您的问题是 class 条件的 [] 换行。 这应该可以解决它:

<div class="card text-dark bg-light border-secondary shadow mt-3 mb-3" :class="!userAnswers[qindex] ? ‘’ : userAnswers[qindex] === correctAnswers[qindex] && answered[qindex] ? 'border-success' : 'border-danger'">

关于你的第二个问题:

也许当您等待响应表单服务器时,userAnswers[qindex] 具有正确答案的值,而 correctAnswers[qindex] 仍未定义(直到您收到响应),并且在这一瞬间,它们彼此不相等 - 这就是为什么您会看到页脚一秒钟然后消失的原因。 所以解决方案是检查:

correctAnswers[qundex] && userAnswers[qindex] !== correctAnswers[qindex]

关于你的第三个问题

我认为最好的解决方案是像您尝试的那样将条件放在 checkAnswer().then 中。您的问题是您检查了 this.answered.length,但 this.answered 是一个对象而不是数组,并且它没有 .length 属性。所以你需要检查是否:

Object.keys(this.answered).length === this.questions.length

所以你的方法应该是:

checkAnswer(qindex, index, value){
      // console.log(qindex, index, value);
      this.answered[qindex] = true;
      this.userAnswers.push(value);
      axios({
        method: 'POST',
        url: 'http://localhost:8990/answercheck',
        data: {
          questionIndex: index,
          choice: value
        }
      }).then((res) => {
        console.log(res.data);
        this.correctAnswers.push(res.data.correctAnswer);
        if(Object.keys(this.answered).length === this.questions.length){
              this.quizResults();
        }
      });
    },

顺便说一下,当您在 mounted() 中调用它时,您的条件不起作用的原因是因为 mounted 仅在加载组件时调用 - 它不监听更改。您可以在 vue docs

中阅读更多相关信息