表單可以通過簡單的v-model實現數據的雙向綁定(value 的單向綁定 + onChange 事件偵聽),實現所見即所得,但表單是限高的,在文本的輸入過程中不能自增高度,因此想到使用div進行數據雙向綁定;
為了實現View=>Model,需要一個可編輯的div,這里使用了contenteditable屬性:
<!-- EditableDiv.vue --> <template> <div ref="div" contenteditable="true"></div> <template/>
v-model並不能直接在div上使用,我們通過mounted周期來模擬插值的過程:
// EditableDiv.vue
export default {
props: ['value'], // 組件接受一個 value 屬性用來在 div 中展示
mounted() {
this.setVal(this.value) // 將 value 注入 div 中
},
methods: {
setVal(val) {
this.$refs.div.innerHTML = val
}
},
watch: {
// 當 props.value 發生改變時 更新 div 中的值
value(val) {
this.setVal(this.value)
}
}
}
這樣就實現了視圖向數據的綁定。
在實現Model=>View的過程中,會有較多頭疼的問題,這篇文章做了很好的總結,但最終還是無法做到像input一樣真實的綁定,只是模擬了行為。
以下是通過blur事件實現的綁定,同樣也是妥協后的結果
<!-- EditableDiv.vue -->
<!-- 為 div 綁定 blur 事件以更新value -->
<template>
<div
ref="div"
contenteditable="true"
@blur="$emit('update:value', $event.target.innerHTML)"
></div>
</template>
在使用時通過sync修飾符:
<!-- Home.vue --> <editable-div :value.sync="content" />
作者:DADFAD
鏈接:https://www.jianshu.com/p/70f592a28c2e
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
在項目中會遇到需要編輯單元格的雙向綁定問題,v-model雙向綁定會在添加contenteditable="true"屬性后失效
解決方法如下,親測好用(v-html和@blur實現):
<td class="width90" contenteditable="true" v-html="name3.LastProduct" @blur="name3.LastProduct=$event.target.innerText"></td>
完美好用!
https://www.cnblogs.com/zhoushuang0426/p/11422421.html
https://www.cnblogs.com/cx709452428/p/10600558.html
vue中用div的contenteditable屬性實現v-for遍歷,雙向數據綁定的動態表格編輯
1.HTML部分
<tr v-for="(item,index) in customerVisitList2" :key="index">
<td class="customerName"><div class="divEdit" contenteditable="true" @blur="blurFunc($event,2,index,'customerName')">{{customerVisitList2[index].customerName}}</div></td>
<td class="visitTime"><div class="divEdit" contenteditable="true" @blur="blurFunc($event,2,index,'visitTime')">{{customerVisitList2[index].visitTime}}</div></td>
<td class="visitDesc"><div class="divEdit" contenteditable="true" @blur="blurFunc($event,2,index,'visitDesc')">{{customerVisitList2[index].visitDesc}}</div></td>
<td class="operation textAlignCenter"><div class="divEdit"><span class="iconfont icon-shanchu hoverStyle" @click="removeCustomerVisit(2,index)"></span></div></td>
</tr>
2.JS部分
blurFunc(e,type,index,name){
//失去焦點實現雙向數據綁定
let content = e.target.innerText
e.target.innerText = ''
if(type === 1){
this.customerVisitList1[index][name] = content
}else{
this.customerVisitList2[index][name] = content
}
e.target.innerText = content
},
addCustomerVisit(type){
//添加行
let index
if(type === 1){
this.customerVisitList1.push({customerType: 'oldCustomer',customerName:'',visitTime:'',visitDesc:''})
}else{
this.customerVisitList2.push({customerType: 'newCustomer',customerName:'',visitTime:'',visitDesc:''})
}
},
removeCustomerVisit(type,index){
//移除行
if(type === 1){
console.log(this.customerVisitList1)
this.customerVisitList1.splice(index,1)
}else{
console.log(this.customerVisitList2)
this.customerVisitList2.splice(index,1)
}
},
3.css部分(stylus)
.divEdit{
outline: none
}
.textAlignCenter{
text-align: center
}
.listTable{
padding 4px 10px 4px 4px
font-size 11px
width 100%
td,th{
padding-left 4px
line-height 24px
width 100%
}
.customerName{
width 150px
}
.visitTime{
width 120px
}
.visitDesc{
width auto
}
.operation{
width 34px
}
}

