Vue3:如何从组件的 setup() 方法访问methods属性内的函数?

问题描述 投票:0回答:1

我有一个包含将要显示的问题数据的数组。一次只能显示一个问题。用户选择问题的答案后,他们可以通过单击按钮或使用向上和向下箭头键移至下一个答案。

这是当前版本的 gif:

App.vue
文件:

import { defineComponent, ref } from 'vue';
import QuestionCard from "./components/QuestionCard.vue";

export default defineComponent({
   components: {
      QuestionCard
   },
   setup() {
      const questionArray = ref([
         {
            id: "123",
            question: "Which of these is a colour in the rainbow?",
            options: [
               'brown', 'red', 'black',
            ],
         }, {
            id: "456",
            question: "How many continents does Earth have?",
            options: [
               1, 7, 6, 9
            ],
         }, {
            id: "789",
            question: "Which of these is a prime number?",
            options: [
               7, 4, 44, 
            ],
         },
      ]);

      let currentQuestion = ref(0);

      return {
         questionArray, currentQuestion
      }
   },
   methods: {
      nextQuestion() {
         if (this.currentQuestion < this.questionArray.length - 1) {
            this.currentQuestion++;
         }
      },
      previousQuestion() {
         if (this.currentQuestion > 0) {
            this.currentQuestion--;
         }
      }
   },
   mounted() {
      console.log('Mounted!!')
      window.addEventListener("keyup", (event) => {
         if (event.code == 'ArrowDown') {
            this.nextQuestion();
         }
         else if (event.code == 'ArrowUp') {
            this.previousQuestion();
         }
      });
   },
   
});
</script>


<template>
   <div>
      <div id="top_bar">
         <button @click="previousQuestion">Previous Question (Up key)</button>
         <button @click="nextQuestion">Next Question (Down key)</button>
      </div>

      <div id="question_section">
         <QuestionCard 
            :question="questionArray[currentQuestion].question"
            :answer_options="questionArray[currentQuestion].options"
         ></QuestionCard>
      </div>
   </div>
</template>

我有一个名为

QuestionCard
的组件,它显示问题和答案选项。就像在
App
组件中一样,我添加了一个事件侦听器,以检测按键操作。每个答案选项都有一个从字母 A (ASCII - 65) 开始的关键代码。例如,根据上面
questionArray
中第一个问题的答案选项,第一个问题的
QuestionCard
只能回答3个关键代码:

  • A 代表棕色
  • B 代表红色
  • C 代表黑色

无论是

  1. 按下分配给答案选项按钮的按键之一,或者
  2. 点击它,

我想记录答案选项值并将其传递给名为

storeAnswer()
的方法。 我通过调用此方法并在单击
<button>
时传递值来实现目标 1。但是,我不太确定如何实现目标 2。

这就是我所做的 - 在

setup()
QuestionCard
方法中,我向窗口添加了侦听器以检测按键释放。在检测时,我检查
key
是否与任何分配给答案选项的键匹配。如果是这样,我调用
storeAnswer()
方法。但是,我收到一条错误消息:

未捕获的引用错误:storeAnswer 未定义

这是

QuestionCard.vue
的代码:

<script lang="ts">
import { defineComponent, ref } from 'vue'

export default defineComponent({
   props: {
      name: String,
      question: String,
      answer_options: Array,
   },
   methods: {
      storeAnswer(ans: any) { 
         this.selectedAns = ans;
         console.log("Button clicked: " + ans);
      }
   },
   setup(props) {
      let selectedAns = ref(null);
      
      // loop through array of answer_options and assign a key code for each one so that it can be detected
      const keyOptions: {keyCode: string, value: any}[] = [];
      for (let i=0; i < props.answer_options.length; i++) {
         keyOptions.push(
            {
               keyCode: String.fromCharCode(65+i),
               value: props.answer_options[i]
            }
         );
      }

      window.addEventListener("keyup", (event) => {
         const keyPressed = event.key.toUpperCase();

         const i = keyOptions.findIndex(Element => Element.keyCode == keyPressed);
         if (i > -1) {            
            selectedAns.value = keyOptions[i].value;
            console.log(`Option you selected is: ${keyPressed + ')' + selectedAns.value}`)
            storeAnswer();
         }
      });

      return {
         selectedAns
      }
   },
});
</script>


<template>
   <div>
      <h4>{{ question }}</h4>
      <div>
         <ul>
            <li v-for="(option, index) in answer_options" :key="index">
               <button @click="storeAnswer(option)">
                  {{  String.fromCharCode(65 + index) + ') ' + option }}
               </button>
            </li>
         </ul>
      </div>

      <!-- display the selected answer -->
      <p>
         {{ selectedAns }}
      </p>
   </div>
</template>
javascript vue.js frontend components vuejs3
1个回答
0
投票

QuestionCard.vue 中突然出现:

if (i > -1) {            
        selectedAns.value = keyOptions[i].value;
        console.log(`Option you selected is: ${keyPressed + ')' + selectedAns.value}`)
        this.storeAnswer();
     }

你把this.storeAnswer();

© www.soinside.com 2019 - 2024. All rights reserved.