gpt4 book ai didi

javascript - 用 Vue.js 实现一个 "fill-in-the-blank"组件

转载 作者:行者123 更新时间:2023-11-30 19:18:00 26 4
gpt4 key购买 nike

基本上,我想做的是在 Vue.js 中实现一个填空系统,但我无法想出一个合适的设计来处理特定的功能。

这是我到目前为止的进展:Vue 组件采用一个名为 sentence 的 prop,它遵循以下格式:“这是一个 [test] sentence for [demonstration] purposes”。

应该显示为空输入字段的词被放在方括号中。这是它应该喜欢的: screenshot

我在计算属性的帮助下实现了这一点:

computed: {
sentence_parts: function () {
return this.sentence.split(/\[([^\]]*)\]/)
}
}

并使用以下 HTML 代码:

<template>
<div>
<span v-for="(part, index) in sentence_parts" v-bind:key="index">
<span v-if="index % 2 == 0">{{part}}</span>
<span v-else><input type="text" v-bind:aria-colindex="index"></span>
</span>
</div>
</template>

基本上,我将字符串转换为数组,将索引为偶数的句子部分放入一个跨度中,而索引为非奇数的句子部分由输入标记替换。

现在回答我的主要问题:实现允许将当前输入与“应该输入”(即句子数组中的输入)进行比较的功能的最佳方法是什么。

我能想到的唯一想法是让输入成为数组字段的模型,但问题是我不想用用户输入覆盖原始数组的条目,但我想保存它变成一个“单独的变量”,然后我可以从一个函数访问它。

可能可行的一件事是创建一个长度为原始数组长度一半的新数组,将它们绑定(bind)到相应的字段,然后通过将其乘以 2(用于比较)来计算它在原始数组中的位置,但我想知道是否有更有效的方法。

(对于上下文,我正在开发一个允许用户测试他们的语法知识的应用程序。)

提前致谢!

最佳答案

这是我的尝试:

const FillInTheBlanks = {
template: `
<div>
<span v-for="(part, index) in sentenceParts" :key="index">
<input
v-if="part.input"
v-model="part.guess"
:aria-colindex="index"
:class="{ correct: partIsCorrect(part) }"
>
<span v-else>{{ part.text }}</span>
</span>
<p v-if="allCorrect">All done!</p>
</div>
`,

props: { sentence: String },

data () {
return {
sentenceParts: []
}
},

computed: {
allCorrect () {
return this.sentenceParts.every(this.partIsCorrect)
}
},

methods: {
partIsCorrect (part) {
return !part.input || part.text === part.guess
},

reset () {
const re = /(\[[^\]]*\])/

// The filter removes empty strings
const parts = this.sentence.split(re).filter(text => text)

this.sentenceParts = parts.map(segment => {
const isInput = re.test(segment)

return {
guess: '',
input: isInput,
text: isInput ? segment.slice(1, -1) : segment
}
})
}
},

watch: {
sentence: {
immediate: true,
handler: 'reset'
}
}
}

new Vue({
el: '#app',

components: {
FillInTheBlanks
},

data () {
return {
sentence: 'This is a [test] sentence for [demonstration] purposes'
}
}
})
.correct, p {
background: #7c7;
}
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
Input sentence: <input v-model="sentence" style="width: 400px">
<br>
<br>
<fill-in-the-blanks :sentence="sentence"></fill-in-the-blanks>
</div>

问题中描述的方法似乎完全合法,我只是想探索一个替代方案。

最初我打算有两个数据结构,一个计算属性(如问题中所示)和 data 中的一些东西保存用户输入。但我也想清除用户输入,如果 sentence Prop 改变了。为此,我需要使用 watchdata中删除相关属性.一旦我有了watch实际上,完全放弃计算属性并将所有内容放在 data 中的一个数组中似乎更容易。 .

显然使用了 watch而不是计算属性设置警钟响起。然而:

  1. 替代方案仍然需要 watch .
  2. 改变计算属性的输出绝对不是一个可行的选择。
  3. 尝试使两个数据结构保持同步会附加其自身的健康警告。

所以我决定摆脱计算属性是可用的妥协选项中最不坏的。根据 future 的需求,这个决定可能需要重新考虑,但现在似乎可以降低复杂性。

我尽量不使用偶数/奇数假设来确定是否使用 <input> .具体来说,我想处理一个 <input>一开始,尽管可以通过在开头放置一个虚拟空间来实现这一点。我还希望它能够处理连续的输入,尽管在实践中这似乎不太可能是必需的,因为我认为它们之间至少总是有一个空格。

关于javascript - 用 Vue.js 实现一个 "fill-in-the-blank"组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57792735/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com