javascript - 在Vue中的网格中单击特定项目时添加类
问题描述
我有一个项目网格(在 flexbox 中创建以便使用 v-for 循环)。我想.selected
在单击列表中的特定项目时添加类。存在一个问题,即每列中的 item 获取的类应该只应用于单个元素。我应该怎么做才能让它工作?
网格:
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>
解决方案
你的想法是正确的。问题出在你的数据结构上。
您只有 7 个项目 - 但您希望它们表现得像 8 行,每行 7 个项目。您的数据对象应该反映您在 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()
.
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: []
}
}
}
推荐阅读
- java - Kafka Java API Rest 代理
- javascript - 具有嵌套对象的多个对象的展平数组
- r - 通过另一个向量的某种外观归档整个向量
- java - git pull IntelliJ IDEA Ultimate 后的 ClassNotFound 异常
- r - 计算数据框中另一个变量级别内的级别数
- javascript - ./index.html 中的语法错误
- react-native - 从不同的地方设置风格
- python - 如何“旋转更长时间”并同时填充列名中的字段?
- css - 如何从 django HTML 模板逻辑中更改 CSS 属性
- xamarin.forms - 如何稳定Android Resource.designer.cs文件