v-for 使操作应用于所有 div [英] v-for causing actions to be applied to all divs
问题描述
之前我问过一个关于在 Vue 中删除自定义 truncate 过滤器的问题.请在此处查看问题:
但是,我忽略了我正在使用 v-for 循环,当我将鼠标悬停在一个 div 上时,我注意到循环中的所有 div 都对它们应用了相同的操作.我不确定如何只定位悬停在上面的 div.这是我的模板:
<button class="tile" v-for="(word, index) in shuffled" @click="clickWord(word, index)" :title="word.english"><div class="pinyin">{{ word.pinyin }}</div><div class="eng" @mouseover="showAll = true" @mouseout="showAll = false"><div v-if="showAll">{{ word.english }}</div><div v-else>{{ word.english |截断 }}</div>按钮>
以及返回的数据:
数据(){返回 {当前索引:0,圆形清除:假,clickedWord: '',matchFirstTry: 真,全部显示:假,}},
如果您了解 Vue,我将不胜感激.谢谢!
在您的示例中, showAll
用于 v-for 生成的每个按钮来确定是否显示word.english
值的完整文本.这意味着每当任何 .engcode> 类 div 的
mouseover
事件触发时,相同的 showAll
属性都会为每个按钮设置为 true.
我会将 showAll
布尔值替换为最初设置为 null
的 showWordIndex
属性:
data() {显示词索引:空,},
然后在模板中,将 showWordIndex
设置为 mouseover
处理程序上单词的 index
(并设置为 null
在 mouseleave
处理程序中):
Previously I asked a question about removing a custom truncate filter in Vue. Please see the question here:
Removing a Vue custom filter on mouseover
However, I neglected to mention that I am using a v-for loop and when I hover over one div, I am noticing that all the divs in the loop are having the same action applied to them. I'm not sure how to target only the div that is being hovered over. Here is my template:
<div id="tiles">
<button class="tile" v-for="(word, index) in shuffled" @click="clickWord(word, index)" :title="word.english">
<div class="pinyin">{{ word.pinyin }}</div>
<div class="eng" @mouseover="showAll = true" @mouseout="showAll = false">
<div v-if="showAll">{{ word.english }}</div>
<div v-else>{{ word.english | truncate }}</div>
</div>
</button>
</div>
And the data being returned:
data(){
return {
currentIndex: 0,
roundClear: false,
clickedWord: '',
matchFirstTry: true,
showAll: false,
}
},
If you know Vue, I would be grateful for advice. Thanks!
In your example, showAll
is being used for each of the buttons generated by the v-for to determine whether or not to show the complete text of the word.english
value. This means that whenever the mouseover
event of any the .eng
class divs fires, the same showAll
property is being set to true for every button.
I would replace the showAll
Boolean value with a showWordIndex
property initially set to null
:
data() {
showWordIndex: null,
},
And then in the template, set showWordIndex
to the index
of the word on the mouseover
handler (and to null
in the mouseleave
handler):
<button v-for="(word, index) in shuffled" :key="index">
<div class="pinyin">{{ word.pinyin }}</div>
<div
class="eng"
@mouseover="showWordIndex = index"
@mouseout="showWordIndex = null"
>
<div v-if="showWordIndex === index">{{ word.english }}</div>
<div v-else>{{ word.english | truncate }}</div>
</div>
</button>
Even better would be to make a new component to encapsulate the functionality and template of everything being rendered in the v-for
, passing the properties of each word
object to the child component as props.
This way, you would still use the showAll
property like you are in your example, but you would define it in the child component's scope. So now the showAll
property will only affect the instance of the component it's related to.
Below is an example of that:
Vue.component('tile', {
template: '#tile',
props: ['pinyin', 'english'],
data() {
return { showAll: false };
},
filters: {
truncate: function(value) {
let length = 50;
if (value.length <= length) {
return value;
} else {
return value.substring(0, length) + '...';
}
}
},
})
new Vue({
el: '#app',
data() {
return {
words: [
{pinyin: 1, english: "really long string that will be cut off by the truncate function"},
{pinyin: 2, english: "really long string that will be cut off by the truncate function"},
{pinyin: 3, english: "really long string that will be cut off by the truncate function"},
{pinyin: 4, english: "really long string that will be cut off by the truncate function"},
],
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.min.js"></script>
<div id="app">
<tile v-for="word, i in words" v-bind="word" :key="word"></tile>
</div>
<script id="tile" type="x-template">
<button :title="english">
<div class="pinyin">{{ pinyin }}</div>
<div class="eng" @mouseover="showAll = true" @mouseout="showAll = false">
<div v-if="showAll">{{ english }}</div>
<div v-else>{{ english | truncate }}</div>
</div>
</button>
</script>
这篇关于v-for 使操作应用于所有 div的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!