如何使用函数制作 v-for 下拉文本?
How to make v-for drop-down text with a function?
我想做一个文本更正,我可以点击错误的单词并从列表中选择一个更正(有点像 Grammarly 做的)。
这个简单的例子应该可以帮助您理解这个想法。假设我有一个从服务器返回的对象列表:
data: {
objects: [
{
word: "This",
val: 0.1,
corrections: {"that", "Those"}
},
{
word: "kat",
val: 0.9,
corrections: {"cat", "cats", "dogs", "animals"}
}
]
}
现在我想写一个 v-for 它将:
- 像普通文本一样显示所有单词(例如 "This kat")
- 对于
val < 0.5
的单词只显示一个 word
- 对于带有
val >= 0.5
的单词显示带有红色下划线的 word
,并且能够单击并查看包含所有 corrections
的下拉列表
- 在下拉列表中选择一个选项后更改对象的值
word
。
最小可重现(无效)示例:
Vue.component('post-list', {
data: function() {
return {
objects: [{
word: "This",
val: 0.1,
corrections: [
"that",
"Those"
]},
{
word: "kat",
val: 0.9,
corrections: [
"cat",
"cats",
"dogs",
"animals"
]}
]
}
},
});
new Vue({
el: '#vue-app'
});
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="vue-app" class="container">
<post-list inline-template>
<div>
<template class="post" v-for="object in objects">
{{ object.word }}
</template>
</div>
</post-list>
</div>
所以基本上您是要我们在大约 10 分钟内为您创建 "Grammarly" 的副本?
好的,接受挑战。我已经创建了一个工作但粗略的示例来为您提供一个起点,也许还有一些关于如何改进它的想法。请记住,这不是最好的解决方案,因为我没有花很多时间考虑它:
演示 https://codepen.io/aQW5z9fe/pen/MWaQjdX
此外,我会将 getFormattedData()
方法移动到服务器,以便您获得具有 underlined
属性以及 val
和 corrections
的格式化数据,而不是重新-在客户端计算它。
<v-menu
v-model="correctionsListIsVisible"
>
<v-list dense>
<v-list-item
v-for="(correction, index) in correctionsListItems"
:key="index"
@click="applyCorrection(correction)"
>
<v-list-item-content>
<v-list-item-title>
{{correction}}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-menu>
<div class="flex">
<div v-for="(object, index) in getFormattedData" class="flex">
<div
@click="toggleCorrectionsList(object)"
:class="{'underlined': object.underlined}"
id="word"
>{{ object.word }}
</div>
<div v-if="addSpace(index)"> </div>
</div>
</div>
data () {
return {
correctionsListIsVisible: false,
correctionsListItems: [],
activeObject: {},
objects: [
{
word: "This",
val: 0.1,
corrections: ["that", "Those"]
},
{
word: "kat",
val: 0.9,
corrections: ["cat", "cats", "dogs", "animals"]
},
{
word: "is",
val: 0.1,
corrections: []
},
{
word: "cute",
val: 0.2,
corrections: []
},
]
}
},
computed: {
getFormattedData() {
let result = []
for (const item of this.objects) {
let object = {}
if (item.val < 0.5) {
object.word = item.word
object.underlined = false
object.corrections = []
}
else if (item.val >= 0.5) {
object.word = item.word
object.underlined = true
object.corrections = item.corrections
}
result.push(object)
}
return result
}
},
methods: {
addSpace (index) {
return index !== (this.getFormattedData.length - 1)
},
toggleCorrectionsList (object) {
if (object.underlined) {
this.correctionsListItems = object.corrections
this.activeObject = object
this.correctionsListIsVisible = true
}
else {
this.activeObject = {}
}
},
applyCorrection (correction) {
this.activeObject.word = correction
this.activeObject.underlined = false
}
}
我想做一个文本更正,我可以点击错误的单词并从列表中选择一个更正(有点像 Grammarly 做的)。
这个简单的例子应该可以帮助您理解这个想法。假设我有一个从服务器返回的对象列表:
data: {
objects: [
{
word: "This",
val: 0.1,
corrections: {"that", "Those"}
},
{
word: "kat",
val: 0.9,
corrections: {"cat", "cats", "dogs", "animals"}
}
]
}
现在我想写一个 v-for 它将:
- 像普通文本一样显示所有单词(例如 "This kat")
- 对于
val < 0.5
的单词只显示一个word
- 对于带有
val >= 0.5
的单词显示带有红色下划线的word
,并且能够单击并查看包含所有corrections
的下拉列表
- 在下拉列表中选择一个选项后更改对象的值
word
。
最小可重现(无效)示例:
Vue.component('post-list', {
data: function() {
return {
objects: [{
word: "This",
val: 0.1,
corrections: [
"that",
"Those"
]},
{
word: "kat",
val: 0.9,
corrections: [
"cat",
"cats",
"dogs",
"animals"
]}
]
}
},
});
new Vue({
el: '#vue-app'
});
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="vue-app" class="container">
<post-list inline-template>
<div>
<template class="post" v-for="object in objects">
{{ object.word }}
</template>
</div>
</post-list>
</div>
所以基本上您是要我们在大约 10 分钟内为您创建 "Grammarly" 的副本?
好的,接受挑战。我已经创建了一个工作但粗略的示例来为您提供一个起点,也许还有一些关于如何改进它的想法。请记住,这不是最好的解决方案,因为我没有花很多时间考虑它:
演示 https://codepen.io/aQW5z9fe/pen/MWaQjdX
此外,我会将 getFormattedData()
方法移动到服务器,以便您获得具有 underlined
属性以及 val
和 corrections
的格式化数据,而不是重新-在客户端计算它。
<v-menu
v-model="correctionsListIsVisible"
>
<v-list dense>
<v-list-item
v-for="(correction, index) in correctionsListItems"
:key="index"
@click="applyCorrection(correction)"
>
<v-list-item-content>
<v-list-item-title>
{{correction}}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-menu>
<div class="flex">
<div v-for="(object, index) in getFormattedData" class="flex">
<div
@click="toggleCorrectionsList(object)"
:class="{'underlined': object.underlined}"
id="word"
>{{ object.word }}
</div>
<div v-if="addSpace(index)"> </div>
</div>
</div>
data () {
return {
correctionsListIsVisible: false,
correctionsListItems: [],
activeObject: {},
objects: [
{
word: "This",
val: 0.1,
corrections: ["that", "Those"]
},
{
word: "kat",
val: 0.9,
corrections: ["cat", "cats", "dogs", "animals"]
},
{
word: "is",
val: 0.1,
corrections: []
},
{
word: "cute",
val: 0.2,
corrections: []
},
]
}
},
computed: {
getFormattedData() {
let result = []
for (const item of this.objects) {
let object = {}
if (item.val < 0.5) {
object.word = item.word
object.underlined = false
object.corrections = []
}
else if (item.val >= 0.5) {
object.word = item.word
object.underlined = true
object.corrections = item.corrections
}
result.push(object)
}
return result
}
},
methods: {
addSpace (index) {
return index !== (this.getFormattedData.length - 1)
},
toggleCorrectionsList (object) {
if (object.underlined) {
this.correctionsListItems = object.corrections
this.activeObject = object
this.correctionsListIsVisible = true
}
else {
this.activeObject = {}
}
},
applyCorrection (correction) {
this.activeObject.word = correction
this.activeObject.underlined = false
}
}