vue.js不更新嵌套v-for循环中的属性
我正在玩vue.js并作出反应,并且我正在尝试修改一本简单的可编辑HTML表格示例为了学习Vue。vue.js不更新嵌套v-for循环中的属性
这里是代码会发生什么:
- 用户点击TD元素TD元素的
- 坐标存储在ROWSEL上,COLSEL变量
- 坐标变化导致Vue的重新渲染视图
- 用户点击的td单元格添加了“contenteditable = true”属性,并添加了聚焦事件监听器
- 用户可以更改td单元格中的数据,然后单击o FF细胞停止编辑(事件的内容触发)
- 当用户点击断电池中,ROWSEL和COLSEL变量被复位从而导致重新渲染
- VUE重新呈现视图,并且由于坐标被复位,Vue的应该删除CONTENTEDITABLE和有关从TD元件事件的内容
- 包含表数据的数据阵列将随后与文本来更新所述用户输入时,此单元为可编辑的(尚未实现)
的我遇到的问题是与第7步。我可以单击我的表中的多个单元格和所有的单元格将仍然contenteditabl e =“true”设置在它们中。如果您查看Chrome开发工具,您会看到contenteditable标签粘贴到所有单击的单元格上。
我相信问题是由于嵌套for循环而发生的,但我不知道如何正确地向它们添加键以使其工作。我试图添加键,但我认为我没有正确地做。
的jsfiddle: https://jsfiddle.net/o69yaq7L/
下面是代码:
"use strict";
var headers = [
"Book", "Author", "Language", "Published", "Sales"
];
var data = [
["The Lord of the Rings", "J. R. R. Tolkien", "English", "1954-1955", "150 million"],
["Le Petit Prince (The Little Prince)", "Antoine de Saint-Exupéry", "French", "1943", "140 million"],
["Harry Potter and the Philosopher's Stone", "J. K. Rowling", "English", "1997", "107 million"],
["And Then There Were None", "Agatha Christie", "English", "1939", "100 million"],
["Dream of the Red Chamber", "Cao Xueqin", "Chinese", "1754-1791", "100 million"],
["The Hobbit", "J. R. R. Tolkien", "English", "1937", "100 million"],
["She: A History of Adventure", "H. Rider Haggard", "English", "1887", "100 million"],
];
var Excel = new Vue({
\t el: '#app',
\t data: {
\t \t colData: data,
\t \t headers: headers, \t \t
\t \t colSel: -1,
\t \t rowSel: -1
\t },
\t methods: {
\t \t dataClick: function(ev){ \t
\t \t \t this.colSel = ev.target.cellIndex;
\t \t \t this.rowSel = ev.target.parentElement.rowIndex - 1;
\t \t \t Vue.nextTick(function(){
\t \t \t \t ev.target.focus();
\t \t \t });
\t \t },
\t \t lostFocus: function(ev){ \t \t \t \t \t \t
\t \t \t console.log(ev.target.textContent);
\t \t \t //var changedRow = this.colData.slice(this.rowSel,this.rowSel+1);
\t \t \t this.colSel = -1;
\t \t \t this.rowSel = -1;
\t \t \t console.log(this.colSel + " " + this.rowSel);
\t \t \t
\t \t }
\t }
});
<html>
<head>
<title>
VUEJS Testing
</title>
</head>
<body>
<div id="app">
<table>
<thead>
<tr>
<th v-for="item in headers" :key="item.id">{{item}}</th>
</tr>
</thead>
<tbody>
<tr v-for="(row,rowInd) in colData" :key="row.id">
\t <template v-for="(item,colInd) in row" >
\t \t <template v-if="rowInd == rowSel && colInd == colSel">
\t \t <td contenteditable="true" v-on:focusout="lostFocus" :key="item.id">{{item}}</td>
\t </template>
\t <template v-else>
\t \t <td v-on:dblclick="dataClick">{{item}}</td>
\t </template>
</template>
</tr>
</tbody>
</table>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.min.js"></script>
</body>
</html>
编辑***
的问题是与此部分代码:
<tr v-for="(row,rowInd) in colData" :key="row.id">
<template v-for="(item,colInd) in row">
<template v-if="rowInd == rowSel && colInd == colSel">
<td contenteditable="true" v-on:focusout="lostFocus" :key="item.id">{{item}}</td>
</template>
<template v-else>
<td v-on:dblclick="dataClick">{{item}}</td>
</template>
</template>
</tr>
有两个V for循环和if-else语句。问题在于if语句使得td元素具有contenteditable = true属性。一旦td元素获得该属性,属性就不会离开,即使在进一步重新呈现td后仍然会有contenteditable = true集合,即使if语句的那部分不会再次影响元素。我认为我使用id标签的方式存在问题,但我不确定如何解决此问题。
你必须给不同的键都if/else语句,像下面:
<tr v-for="(row,rowInd) in colData" :key="row.id">
<template v-for="(item,colInd) in row" >
<template v-if="rowInd == rowSel && colInd == colSel">
<td contenteditable="true" v-on:focusout="lostFocus" :key="item.id" key="key1">{{item}}</td>
</template>
<template v-else>
<td v-on:dblclick="dataClick" key="key2">{{item}}</td>
</template>
</template>
</tr>
查看更新后的fiddle。
发生这种情况是因为Vue尝试尽可能高效地呈现元素,通常重新使用它们而不是从头开始呈现。既然在你的情况下,如果和其他templace使用相同的元素,不会被替换,只是它的点击事件。尽管这并不总是令人满意的,所以Vue提供了一种方法让您说,These two elements are completely separate - don’t re-use them,可以通过将key
属性添加到唯一值来完成。
你能告诉我什么区别“键“和”:键“(前面有冒号的键)是?我在Vue网站上看到了使用“:key”添加密钥的参考资料,例如:https://vuejs.org/v2/guide/list.html#key。 – kholdstayr
':key'相当于'v-bind:key',它用来将它绑定到动态值,即i。即任何vue实例都是可变的。 – Saurabh
请更新代码显示值,它必须显示调试它作为目前它只是表和很难说什么是因为vue-devtools不工作在jsfiddle –