simple quiz vue component
This commit is contained in:
1 parent
eb51015c6c
commit
b2aa693f1a
3 files changed
+157
No files matched your search
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div id="sentence-quiz" :class="$style.root" ref="main">
|
||||
<button type="button" @click="nextSentence()">Next</button>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, ref, useTemplateRef } from "vue";
|
||||
|
||||
const mainEl = useTemplateRef("main");
|
||||
const sentences = ref<number[]>([]);
|
||||
const sentences_array_index = ref(NaN);
|
||||
|
||||
function nextSentence() {
|
||||
if (!mainEl.value) return;
|
||||
|
||||
const getCurrentSentenceIndex = () => {
|
||||
if (sentences.value.length <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (++sentences_array_index.value < sentences.value.length) {
|
||||
return sentences.value[sentences_array_index.value];
|
||||
}
|
||||
|
||||
sentences.value = sentences.value
|
||||
.map((s) => ({ s, k: Math.random() }))
|
||||
.sort((a, b) => a.k - b.k)
|
||||
.map((a) => a.s);
|
||||
|
||||
sentences_array_index.value = 0;
|
||||
|
||||
return sentences.value[sentences_array_index.value];
|
||||
};
|
||||
|
||||
const currentSentenceIndex = getCurrentSentenceIndex();
|
||||
|
||||
mainEl.value.querySelectorAll("#sentence-quiz > ul > li").forEach((el, i) => {
|
||||
if (!(el instanceof HTMLElement)) return;
|
||||
el.style.display = i === currentSentenceIndex ? "" : "none";
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
if (!mainEl.value) return;
|
||||
|
||||
sentences.value = Array.from(
|
||||
mainEl.value.querySelectorAll("#sentence-quiz > ul > li"),
|
||||
).map((el, i) => i);
|
||||
|
||||
nextSentence();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style module>
|
||||
.root {
|
||||
margin-top: 1em;
|
||||
|
||||
&:hover li li {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> button {
|
||||
float: right;
|
||||
border: 1px solid gray;
|
||||
padding: 0 0.5em;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -7,6 +7,7 @@ import { h } from "vue";
|
||||
|
||||
import AudioButton from "./components/AudioButton.vue";
|
||||
import Details from "./components/Details.vue";
|
||||
import SentenceQuiz from "./components/SentenceQuiz.vue";
|
||||
// import PDF from "./components/PDF.vue";
|
||||
import TTS from "./components/TTS.vue";
|
||||
import YouTube from "./components/YouTube.vue";
|
||||
@@ -24,6 +25,7 @@ export default {
|
||||
// ...
|
||||
app.component("AudioButton", AudioButton);
|
||||
app.component("Details", Details);
|
||||
app.component("SentenceQuiz", SentenceQuiz);
|
||||
app.component("TTS", TTS);
|
||||
app.component("YouTube", YouTube);
|
||||
// app.component("PDF", PDF);
|
||||
|
||||
Reference in new issue
Block a user