单击Vue网格中的特定项目后添加课程

时间:2019-06-04 09:22:18

标签: javascript vue.js

我有一个项目网格(在flexbox中创建,以便使用v-for循环)。 我想在单击列表中的特定项目时添加类.selected。 存在一个问题,即每列中的项都获得仅应应用于单个元素的类。我应该怎么做才能使其正常工作?

网格:

new Vue({
  el: "#app",
  data: {
    rows: 8,
    items: [
      {
        selected: false
      },
      {
        selected: false
      },
      {
        selected: false
      },
      {
        selected: false
      },
      {
        selected: false
      },
      {
        selected: false
      },
      {
        selected: false
      }
    ]
  }
})
.app > ul {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 4vh;
  padding-bottom: 4vh;
  border-bottom: 1px solid gray;
}
.app > ul > li.row > ul {
  display: flex;
  margin: 8px 0;
}
.app > ul > li.row > ul li {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background-color: transparent;
  border: 3px solid gray;
  margin: 0 8px;
}
.app > ul > li.row > ul li.selected {
  background-color: gray;
}
ul {
 list-style-type: none;
 padding: 0;
 margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="app">
  <ul>
    <li v-for="row in rows" class="row">
      <ul>
        <li v-for="item, index in items" :key="index" :class="{ selected: item.selected }" @click="item.selected = !item.selected"></li>
      </ul>
    </li>
  </ul>
</div>

1 个答案:

答案 0 :(得分:1)

您在考虑正确的路线。问题出在你的数据结构上。

您只有7个项目-但您希望它们的行为类似于7个项目的8行。您的数据对象应反映您在DOM中循环的结构。

类似的事情就是你所追求的:

new Vue({
  el: "#app",
  data: {
    rows: [
      {
        items: [
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          }
        ]
      },
      {
        items: [
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          }
        ]
      },
      {
        items: [
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          }
        ]
      },
      {
        items: [
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          }
        ]
      },
      {
        items: [
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          }
        ]
      },
      {
        items: [
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          }
        ]
      },
      {
        items: [
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          }
        ]
      },
      {
        items: [
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          },
          {
            selected: false
          }
        ]
      }
    ]
    
  }
})
.app > ul {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 4vh;
  padding-bottom: 4vh;
  border-bottom: 1px solid gray;
}
.app > ul > li.row > ul {
  display: flex;
  margin: 8px 0;
}
.app > ul > li.row > ul li {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background-color: transparent;
  border: 3px solid gray;
  margin: 0 8px;
}
.app > ul > li.row > ul li.selected {
  background-color: gray;
}
ul {
 list-style-type: none;
 padding: 0;
 margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="app">
  <ul>
    <li v-for="(row, rowIndex) in rows" class="row">
      <ul>
        <li v-for="(item, index) in row.items" :key="index + '_' + rowIndex" :class="{ selected: item.selected }" @click="item.selected = !item.selected"></li>
      </ul>
    </li>
  </ul>
</div>

编辑:您不必对这些值进行硬编码。您可以选择使用Vue.$set()在组件mount()(或其他合适的事件)上循环生成它们。

在组件中的Vue.$set()钩中使用mounted()的示例:

export default {
  mounted () {
    const rows = 8
    const itemsPerRow = 7

    for (let r = 0; r < rows; r++) {
      let row = {
        items: []
      }

      for (let i = 0; i < itemsPerRow; i++) {
        row.items.push({
          selected: false
        })
      }

      this.$set(this.rows, r, row)

    }
  },

  data () {
    return {
      rows: []
    }
  }
}