前言
最近做的一個表格,有改某個單元格的需求,經過研究完美實現此功能,以下簡要介紹下實現過程:
所用前端工具
效果圖
實現過程
不拖泥帶水,先看代碼,想知道爲什麼要這樣寫的看下面講解部分
<el-table
:data="dataList"
border
v-loading="loadingFlag"
style="width: 100%;"
size="small"
@selection-change="selectChange"
>
<el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
<el-table-column type="index" align="center" label="序號" width="60"></el-table-column>
<el-table-column
align="center"
label="名稱"
min-width="120"
>
<!--關鍵代碼-->
<template slot-scope="scope">
<el-input v-if="scope.row.isSelected" v-model="scope.row.name" @focus="focusEvent(scope.row)" @blur="blurEvent(scope.row)" v-focus></el-input>
<p @click="cellClick(scope.row)" v-else>{{scope.row.name}}</p>
</template>
</el-table-column>
<el-table-column label="地址" prop="mac" align="center"></el-table-column>
<el-table-column label="類型" prop="type" align="center"></el-table-column>
<el-table-column label="組" prop="group" align="center"></el-table-column>
<el-table-column label="域" prop="zoom" align="center"></el-table-column>
<el-table-column label="創建時間" prop="time" align="center"></el-table-column>
</el-table>
export default {
data () {
return {
dataList: [],
loadingFlag: true
}
},
components: {
PageTitle
},
directives: {
focus: {
inserted: function (el) {
el.querySelector('input').focus()
}
}
},
created () {
this.getList()
},
methods: {
getList () {
this.$http.get('/list').then(res => {
if (res.status === 200) {
this.loadingFlag = false
this.dataList = res.data.map(item => {
return {...item, isSelected: false}
})
console.log(this.dataList)
}
})
},
selectChange (e) {
console.log(e)
},
focusEvent (row) {
row.oldName = row.name
},
blurEvent (row) {
row.isSelected = !row.isSelected
if (row.name !== row.oldName) {
// 。。。此處代碼省略(調用修改名稱接口)
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
})
}
},
cellClick (row) {
row.isSelected = !row.isSelected
}
}
}
內容講解
methods
中getList
方法在拿到後臺數據後給數組對象每一項中添加了同一個屬性isSelected
,即:
this.dataList = res.data.map(item => {
return {...item, isSelected: false}
})
- 有了
isSelected
屬性後我們可以控制每一項名稱的<el-input>
和<p>
標籤的顯示隱藏,從而來實現點擊單元格即自動聚焦修改名稱
<template slot-scope="scope">
<el-input v-if="scope.row.isSelected" v-model="scope.row.name" @focus="focusEvent(scope.row)" @blur="blurEvent(scope.row)" v-focus></el-input>
<p @click="cellClick(scope.row)" v-else>{{scope.row.name}}</p>
</template>
focusEvent
方法是爲了記錄用戶聚焦該行前,該行的name
值:
focusEvent (row) {
row.oldName = row.name
},
- 失去焦點時,比較
oldName
和name
是否相同
blurEvent (row) {
// 目的是爲了讓<el-input>標籤隱藏
row.isSelected = !row.isSelected
if (row.name !== row.oldName) {
// 。。。此處代碼省略(調用修改名稱接口)
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
})
}
},
- 接下來要講爲什麼要用自定義指令
v-focus
,當給<el-input>
標籤添加autofocus
發現無效,然後看到網上提供的思路遂使用vue
框架提供的directives
:
directives: {
focus: {
inserted: function (el) {
el.querySelector('input').focus()
}
}
},
- 目的就是爲了在點擊
<p>
標籤的同時,顯示<el-input>
標籤並使其聚焦 - 這裏說明一下
cellClick
事件之所以加在<p>
標籤上是防止點擊<el-input>
時也觸發cellClick
事件,如果加在它們的父級上會出現我說的這種情況。
總結
之所以要寫這篇文章,是因爲當想實現這個功能的時候發現網上沒有一個講的好的例子,所以花點時間記錄一下,好記性不如爛筆頭,也希望可以幫助到需要的人,覺得不錯的點個贊再走吧!