v-用于使动作应用于所有div

时间:2017-07-19 18:27:55

标签: javascript vue.js vuejs2

之前我问过一个关于在Vue中删除自定义截断过滤器的问题。请在此处查看问题:

Removing a Vue custom filter on mouseover

但是,我忽略了提到我正在使用v-for循环,当我将鼠标悬停在一个div上时,我注意到循环中的所有div都应用了相同的动作。我不确定如何只针对正在盘旋的div。这是我的模板:

 <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>

返回的数据:

  data(){
    return {
      currentIndex: 0,
      roundClear: false,
      clickedWord: '',
      matchFirstTry: true,
      showAll: false,
    }
  },

如果你认识Vue,我将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:2)

在您的示例中,showAll正用于v-for生成的每个按钮,以确定是否显示word.english值的完整文本。这意味着每当mouseover类div的.eng事件触发时,每个按钮都会将相同的showAll属性设置为true。

我会将showAll布尔值替换为最初设置为showWordIndex的{​​{1}}属性:

null

然后在模板中,将data() { showWordIndex: null, }, 设置为showWordIndex处理程序上的单词的index(以及mouseover处理程序中的null

mouseleave

Here's a working fiddle.

更好的做法是创建一个新组件来封装<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> 中呈现的所有内容的功能和模板,将每个v-for对象的属性作为props传递给子组件。

这样,您仍然可以像在示例中一样使用word属性,但是您可以在子组件的范围中定义它。所以现在showAll属性只会影响与其相关的组件的实例。

下面是一个例子:

&#13;
&#13;
showAll
&#13;
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"},
      ],
    }
  }
})
&#13;
&#13;
&#13;

答案 1 :(得分:0)

为了做到这一点,你不能使用计算属性(正如我最初在你的链接答案中所建议的那样),因为你需要知道你所处的上下文。那就是说,你如果将showAll属性应用于每个单独的实例,则可以使用过滤器。如果您在数据模型中预先声明此属性,则该属性将被激活,您可以在鼠标悬停和鼠标移动时单独切换每个项目。

模板:

<div id="app">
  <div id="tiles">
    <div class="tile" v-for="(word, index) in shuffled" :title="word.english">
      <div class="pinyin">{{ word.pinyin }}</div>
      <div class="eng" @mouseover="word.showAll = true" @mouseout="word.showAll = false">
        {{ word.english | truncate(word) }}
      </div>
    </div>
  </div>
</div>

JS:

new Vue({
    el: '#app',
    data() {
        return {
            shuffled: [
                { english: 'here', showAll: false}, 
                { english: 'are', showAll: false }, 
                { english: 'there', showAll: false },
                { english: 'words', showAll: false }
            ],
            currentIndex: 0,
            roundClear: false,
            clickedWord: '',
            matchFirstTry: true,
        }
    },
    filters: {
        truncate: function(value, word) {
            console.log(word)
            let length = 3;
            if (word.showAll || value.length <= length) return value;

            return value.substring(0, length) + '...';
        }
    },
})

见工作JSFiddle

关键是将showAll应用于每个单词实例,然后将该单词实例传递回过滤器,以便我们可以检查showAll属性的值。只要您事先声明,Vue的反应系统会为您处理剩下的事情。

请注意,在此示例中,没有必要使用带有v-if / else的两个元素。带过滤器的单个元素可以很好地工作。