2016-12-07 82 views
2

我正在玩vue.js並作出反應,並且我正在嘗試修改一本簡單的可編輯HTML表格示例爲了學習Vue。vue.js不更新嵌套v-for循環中的屬性

這裏是代碼會發生什麼:

  1. 用戶點擊TD元素TD元素的
  2. 座標存儲在ROWSEL上,COLSEL變量
  3. 座標變化導致Vue的重新渲染視圖
  4. 用戶點擊的td單元格添加了「contenteditable = true」屬性,並添加了聚焦事件監聽器
  5. 用戶可以更改td單元格中的數據,然後單擊o FF細胞停止編輯(事件的內容觸發)
  6. 當用戶點擊斷電池中,ROWSEL和COLSEL變量被複位從而導致重新渲染
  7. VUE重新呈現視圖,並且由於座標被複位,Vue的應該刪除CONTENTEDITABLE和有關從TD元件事件的內容
  8. 包含表數據的數據陣列將隨後與文本來更新所述用戶輸入時,此單元爲可編輯的(尚未實現)

的我遇到的問題是與第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標籤的方式存在問題,但我不確定如何解決此問題。

+0

請更新代碼顯示值,它必須顯示調試它作爲目前它只是表和很難說什麼是因爲vue-devtools不工作在jsfiddle –

回答

1

你必須給不同的鍵都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屬性添加到唯一值來完成。

+0

你能告訴我什麼區別「鍵「和」:鍵「(前面有冒號的鍵)是?我在Vue網站上看到了使用「:key」添加密鑰的參考資料,例如:https://vuejs.org/v2/guide/list.html#key。 – kholdstayr

+1

':key'相當於'v-bind:key',它用來將它綁定到動態值,即i。即任何vue實例都是可變的。 – Saurabh