javascript - Vue v-for : iterate one element individually in an array

标签 javascript html vue.js

我希望循环遍历一系列 span 标签,并将 is-active 添加到行中的下一个标签,每 3 秒一次。我让它工作,但在第一个之后,它添加了所有其余的。如何从事件类中提取该类并将其添加到下一个数组项?

我已经通读了几次官方文档,似乎没有提到迭代单个项目,只是将它们全部列出或将一个项目插入列表。

我不确定“index”是否在这里起作用,以及如何获取span元素的索引来添加/减去is-active。我做错了什么?

var firstComponent = Vue.component('spans-show', {
  template: `
<h1>
	<span class="unset">Make</span>
	<br>
	<span class="unset">Something</span>
    <br>
	<span v-for="(span, index) of spans" :class="{ 'is-active': span.isActive, 'red': span.isRed, 'first': span.isFirst }" :key="index">{{ index }}: {{ span.name }}</span>
</h1>
`,

  data() {
    return {
      spans: [
        {
          name: 'Magical.',
          isActive: true,
          isRed: true,
          isFirst: true
        },
        {
          name: 'Inspiring.',
          isActive: false,
          isRed: true,
          isFirst: true
        },
        {
          name: 'Awesome.',
          isActive: false,
          isRed: true,
          isFirst: true
        }
      ]
    };
  },

  methods: {
    showMe: function() {
      setInterval(() => {
        // forEach
        this.spans.forEach(el => {
          if (el.isActive) {
            el.isActive = false;
          } else {
            el.isActive = true;
          }
        });
      }, 3000);
    }
  },

  created() {
    window.addEventListener('load', this.showMe);
  },

  destroyed() {
    window.removeEventListener('load', this.showMe);
  }
});

var secondComponent = Vue.component('span-show', {
  template: `
<span v-show="isActive"><slot></slot></span>
`,

  props: {
    name: {
      required: true
    }
  },

  data() {
    return {
      isActive: false
    };
  }
});

new Vue({

  el: "#app",
  components: {
    "first-component": firstComponent,
    "second-component": secondComponent
  }
});
.container {
  position: relative;
  overflow: hidden;
  width: 100%;
}

.wrapper {
  position: relative;
  margin: 0 auto;
  width: 100%;
  padding: 0 40px;
}

h1 {
  font-size: 48px;
  line-height: 105%;
  color: #4c2c72;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-family: archia-semibold, serif;
  font-weight: 400;
  margin: 0;
  height: 230px;
}

span {
  position: absolute;
  clip: rect(0, 0, 300px, 0);
}

span.unset {
  clip: unset;
}

span.red {
  color: #e43f6f;
}

span.is-active {
  clip: rect(0, 900px, 300px, -300px);
}
<div id="app">
  <div class="container">
    <div class="wrapper">
      <spans-show>
        <span-show></span-show>
      </spans-show>
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>

最佳答案

为了达到预期的结果,我建议稍微改变一下方法。

我们可以创建一个变量(例如activeSpan),而不是更改单个项目的isActive值,它将负责当前的事件跨度并随着时间的推移而增加它。

setInterval(() => {
  // Increment next active span, or reset if it is the one
  if (this.activeSpan === this.spans.length - 1) {
    this.activeSpan = 0
  } else {
    this.activeSpan++
  }
}, 3000);

在组件的模板中,我们将类 is-active 设置为有条件的并依赖于 activeSpan 变量:

:class="{ 'is-active': index === activeSpan, 'red': span.isRed, 'first': span.isFirst }"

如果您仍然需要更新 spans 数组中的值,可以通过更简单的方式完成,例如通过 map 。还包括以下解决方案中的可选情况。

工作示例: JSFiddle

旁注:无需为 load 事件添加窗口监听器,因为应用程序本身会在 DOM 准备好后加载。相反,可以在 created Hook 内调用方法。它包含在上面的解决方案中。

关于javascript - Vue v-for : iterate one element individually in an array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53163337/

相关文章:

Javascript:在视口(viewport)中动画 Div

html - 在事件菜单项的左侧添加一个点

javascript - 观察 Vue.js 计算属性在控制台中返回循环数据

vue.js - npm run build --mode [.env.mode] 没有按预期工作

javascript - Vue CLI插件Electron Builder在构建时显示完整的空白屏幕

javascript - 桌面通知中的自定义/样式标题和正文方向(chrome)

javascript - JS - 从 FireFox 选择子节点时出现问题

javascript - 通过异步函数传递变量

javascript - 需要时突出显示带有红色边框的文本框

jquery - 着陆页的不同变体