各位大大好
有一頁面,該功能為
表單在網頁載入時ajax到後端之後取回內容並渲染
若想編輯某列的值
使用 jquery 的作法:
按下按鈕->取得該列(clickRow)->取得編輯前的值
->clone template tr (newRow)-> newRow裡input填入編輯前的值
->把newRow新增到clickRow之後
<table id="mainTB">
<thead>
<th>日期</th>
<th>筆記</th>
<th>動作</th>
</thead>
<tbody id="mainTBody">
<tr>
<td>date<td>
<td>note<td>
<td>
<input type="button" name="edit" value="編輯" onclick="edit(this);">
</td>
</tr>
</tbody>
</table>
<div id="template">
<table>
<tr name="tmpRow">
<td><input type="date" name="noteDate"><td>
<td><input type="text" name="noteText"><td>
<td>
<input type="button" name="update" value="更新">
<input type="button" name="cancel" value="取消">
</td>
</tr>
</table>
</div>
<script>
function edit(thisBtn){
var clickRow = $(thisBtn).closest("tr").hide(); //取得編輯按鈕所屬的列 該列隱藏
... //取得clickRow td裡的值 (編輯前的值)
var newRow = $("#template").find("tr[name='tmpRow']").clone();
... //newRow 裡的input 填入編輯前的值
$(clickRow).after(newRow); //新增到要編輯的列之後
}
</script>
以jquery來說就是選擇DOM然後進行相關操作
但如果想用vue來寫
讀取後端並渲染已成功
但若想進行編輯就不曉得該怎麼做了
想請問有甚麼好的建議與做法 謝謝
<tbody>
<tr v-for="(data, index) in notes" :key="index">
<td>{{ data.date }}</td>
<td>{{ data.note }}</td>
<td>
<input type="button" name="editBtn" value="編輯" @click="editFn">
</td>
</tr>
</tbody>
<script>
export default {
data () {
return {
notes: null,
}
},
methods: {
async loadPage(){
try{
let response = await this.$http.get(`...`);
this.notes = response.data;
} catch(err){
window.alert(err)
}
},
editFn(){
//產生編輯列
},
},
async created () {
this.loadPage()
}
}
</script>
編輯欄位設定v-model,將每一列的資料帶到@click事件,更新欄位的v-model
<!--template-->
<input type="button" name="editBtn" value="編輯" @click="editFn(index, data)">
<input type="date" v-model="model.noteDate" name="noteDate">
<input type="text" v-model="model.noteText" name="noteText">
// data
model: {
index: null,
noteDate: null,
noteText: null
},
// methods
editFn (index, data) {
this.model.index = index;
this.model.noteDate = data.date;
this.model.noteText = data.note;
},
編輯完後,將v-model的值,塞回特定index的資料,即可更新編輯的資料
<!--template-->
<input type="button" name="update" value="更新" @click="updateRow">
// methods
updateRow () {
this.notes[this.model.index].date = this.model.noteDate;
this.notes[this.model.index].note = this.model.noteText;
}
參考Sample:
<template>
<div>
<table>
<thead>
<th>日期</th>
<th>筆記</th>
<th>動作</th>
</thead>
<tbody>
<template v-for="(data, index) in notes">
<tr>
<td>{{ data.date }}</td>
<td>{{ data.note }}</td>
<td>
<input type="button" name="editBtn" value="編輯" @click="editFn(index, data)">
</td>
</tr>
<tr name="tmpRow" v-if="model.index === index">
<td><input type="date" v-model="model.noteDate" name="noteDate"></td>
<td><input type="text" v-model="model.noteText" name="noteText"></td>
<td>
<input type="button" name="update" value="更新" @click="updateRow">
<input type="button" name="cancel" value="取消" @click="clearTempRow">
</td>
</tr>
</template>
</tbody>
</table>
</div>
</template>
<script>
export default {
data () {
return {
model: {
index: null,
noteDate: null,
noteText: null
},
notes: null,
}
},
methods: {
async loadPage () {
try{
let response = await this.$http.get(`...`);
this.notes = response.data;
} catch(err){
window.alert(err)
}
},
editFn (index, data) {
this.model.index= index;
this.model.noteDate = data.date;
this.model.noteText = data.note;
},
updateRow () {
this.notes[this.model.index].date = this.model.noteDate;
this.notes[this.model.index].note = this.model.noteText;
this.clearTempRow();
},
clearTempRow () {
this.model.index = null;
this.model.noteDate = null;
this.model.noteText = null;
}
},
async created () {
this.loadPage()
}
}
</script>
謝謝回答
我想請問一下 大大是會怎樣產生出編輯列
原則上Vue的思維,大多時候你不需要自行處理任何DOM Tree的節點操作
Vue的思維比較偏向,當資料(data、computed、watch)在什麼狀態下,畫面(template)該怎麼呈現
關於編輯列顯示隱藏的部分
我是預先寫好在Vue Template當中,使用v-show控制在編輯的時候才顯示
當你按下編輯時,model.index !== null 編輯列就會顯示
當你完成編輯後,model.index === null 編輯列就不會顯示
<!--model.index !== null (編輯時),才顯示編輯列-->
<tr name="tmpRow" v-show="model.index !== null">
</tr>
另外補充一下,也可以使用v-if,但兩者不太一樣:
如果你不希望編輯列的HTML存在,就可以改使用v-if
可是這樣的話不管是編輯哪一列 編輯列都會出現在表單的最下面 對吧? 有辦法出現在欲編輯列的下面嗎?
如果你要改成在指定列下方的話,可以使用 <template> 包住兩個tr
一個是資料列,一個是編輯列
編輯列再用v-if判斷,判斷是否顯示正在編輯的資料
<tbody>
<template v-for="(data, index) in notes">
<tr>
<td>{{ data.date }}</td>
<td>{{ data.note }}</td>
<td>
<input type="button" name="editBtn" value="編輯" @click="editFn(index, data)">
</td>
</tr>
<tr name="tmpRow" v-if="model.index === index">
<td><input type="date" v-model="model.noteDate" name="noteDate"></td>
<td><input type="text" v-model="model.noteText" name="noteText"></td>
<td>
<input type="button" name="update" value="更新" @click="updateRow">
<input type="button" name="cancel" value="取消" @click="clearTempRow">
</td>
</tr>
</template>
</tbody>
謝謝回答 我知道關鍵所在了
這應該比你使用 jQuery 的時候好寫很多
codepen
謝謝回答 大大做法我大約了解了
listennn08
你一開始寫的版本我覺得也不錯,而且比較直觀
直接原資料列替換input跟文字
通靈亡
他說要放下面所以我就改成放下面的版本XD
然後有想到如果不要替換要能變成替換前的值,又多存了改變之前的值
不然用 v-model 就會直接換掉了